共计 2242 个字符,预计需要花费 6 分钟才能阅读完成。
接口中的 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'); |
输入:
正文完
发表至: javascript
2022-03-25