什么是 constructor signature in interface

简介: 什么是 constructor signature in interface

接口中的 constructor signature 不能在类中实现; 它们仅用于定义定义 newable 的现有 JS API. 下面是一个例子:

interface ComesFromString {
    name: string;
}
意思是这个接口代表一个可以使用 `new` 操作符操作的对象。返回的类型是 ComesFromString
interface StringConstructable {
    new(n: string): ComesFromString;
}
class MadeFromString implements ComesFromString {
    constructor (public name: string) {
        console.log('ctor invoked');
    }
}
// 下面函数定义了一个工厂方法。工厂方法的输入就是之前定义的 constructor signature
function makeObj(n: StringConstructable) {
    return new n('hello!');
}
console.log(makeObj(MadeFromString).name);

执行结果:

以上例子实际上为 makeObj 的函数调用创建了一个 constraint,传入的输入参数必须可以被 new 操作施加,并且构造函数仅包含一个输入参数,类型为 string.

下列代码会引起编译错误:

class Other implements ComesFromString {
    constructor (public name: string, count: number) {
    }
}
makeObj(Other); 

Argument of type ‘typeof Other’ is not assignable to parameter of type ‘StringConstructable’.(2345)

添加问号将其设置为 optional 参数后,问题消失:


具有构造签名的接口并不意味着由任何类实现(乍一看,这对于一些具有 C#/Java 背景的开发人员来说可能看起来很奇怪,但这确实是另一种不同的设计思路)。


暂时把它想象成一个带有调用签名的接口(就像Java世界中的@FunctionalInterface)。 它的目的是描述一种函数类型。所描述的签名应该由函数对象满足。但不仅仅是任何高级函数或方法。 它应该是一个知道如何构造对象的函数,一个在使用 new 关键字时被调用的函数。


因此,带有构造签名的接口定义了构造函数的签名。如上图我举过的例子,makeObj 函数只接受构造函数仅仅包含唯一一个输入参数且数据类型为 string.


例子:

interface ClassicInterface { // old school interface like in C#/Java
    method1():string;
    methodN():string;
}
interface Factory { //knows how to construct an object
    // NOTE: pay attention to the return type
    new (myNumberParam: number, myStringParam: string): ClassicInterface
}
class MyImplementation implements ClassicInterface {
    // The constructor looks like the signature described in Factory
    constructor(num: number, s: string) { 
      console.log('in myImplementation:', num, s);
    } // obviously returns an instance of ClassicInterface
    method1() {
      return '1';
    }
    methodN() {
      return '2';
    }
}
class MyOtherImplementation implements ClassicInterface {
    // The constructor looks like the signature described in Factory
    constructor(n: number, s: string) { 
      console.log('in myOtherImplementation:', n, s);
    } // obviously returns an instance of ClassicInterface
    method1() {
      return '3';
    }
    methodN() {
      return '4';
    }
}
// And here is the polymorphism of construction
function instantiateClassicInterface(ctor: Factory, myNumberParam: number, myStringParam: string): ClassicInterface {
    return new ctor(myNumberParam, myStringParam);
}
// And this is how we do it
let iWantTheFirstImpl = instantiateClassicInterface(MyImplementation, 3.14, "smile");
let iWantTheSecondImpl = instantiateClassicInterface(MyOtherImplementation, 42, "vafli");
console.log('done');



相关文章
|
2月前
FeignClient【问题】Cannot deserialize value of type``from Object value (token `JsonToken.START_OBJECT`)
FeignClient【问题】Cannot deserialize value of type``from Object value (token `JsonToken.START_OBJECT`)
390 0
error : Class declarations lacks Q_OBJECT macro
error : Class declarations lacks Q_OBJECT macro
|
IDE Java 开发工具
Lombok - Generating equals/hashCode implementation but without a call to superclass
Lombok - Generating equals/hashCode implementation but without a call to superclass
1055 0
|
Java Android开发
The method call() of type XXX must override a superclass
The method call() of type XXX must override a superclass
87 0
|
Java C#
什么是 constructor signature in interface
什么是 constructor signature in interface
113 0
什么是 constructor signature in interface
|
Go PHP
【GO】panic: reflect.Value.Interface: cannot return value obtained from unexported field or method
【GO】panic: reflect.Value.Interface: cannot return value obtained from unexported field or method
431 0
【GO】panic: reflect.Value.Interface: cannot return value obtained from unexported field or method
【Junit 报错】Test class should have exactly one public zero-argument constructor和Test class can only have one constructor
错误1: 1 java.lang.Exception: Test class should have exactly one public zero-argument constructor 2 at org.
6083 0
|
前端开发
SpringMVC - Failed to instantiate Specified class is an interface
SpringMVC - Failed to instantiate Specified class is an interface
343 0
|
JavaScript 前端开发
Do not access Object.prototype method 'hasOwnProperty' 问题原因及解决方法
使用Vue.js启动新项目将自动生成配置为与ESLint一起使用的样板。ESLint是可插拔和可配置的Linter工具,可帮助您识别和报告JavaScript中的不良模式,因此您可以轻松维护代码质量。如果您在不受控制的情况下开始编程,则可能会引入一些对ESLint不利的做法。
456 0