我想创建一个类型,它保证一个类接收特定类型作为其构造函数的第一个参数。给定这些定义,
export type UnaryConstructor<Item, Options> = new (
options: Options,
...args: any[]
) => Item;
class AnItemOptions {}
class SomethingElse {}
我想
const item: UnaryConstructor<AnItem, AnItemOptions> = AnItem;
对
进行正确的类型检查// good
class AnItem {
constructor(options: AnItemOptions, somethingElse: SomethingElse);
}
,如果缺少AnItemOptions
参数或顺序混淆,则无法进行类型检查:
// bad!
class AnItem {
constructor(somethingElse: SomethingElse, options: AnItemOptions);
}
class AnItem {
constructor(somethingElse: SomethingElse);
}
然而,上面两个语句都通过了类型检查!
当我尝试定义UnaryConstructor
时,args
不存在,或者unknown[]
或Object[]
类型,我得到不同的错误。
然而,此模式适用于普通函数。如果我写:
type UnaryFunction<Item, Options> = (options: Options, ...args[]) => Item;
然后,如我所料,
// good! typechecks
const fn: UnaryFunction<Item, Options> = (options: Options, somethingElse: SomethingElse) => { return new Item(options, somethingElse); }
类型检查,而相同的函数,参数顺序颠倒
// bad! does not typecheck
const fn: UnaryFunction<Item, Options> = (somethingElse: SomethingElse, options: Options) => { return new Item(options, somethingElse); }
不进行类型检查。
你知道为什么类型检查似乎只在构造函数上失效吗?
您的代码运行良好。AnItemOptions
和SomethingElse
是结构相同的,因为它们只是空接口。没有任何区分结构,它们可以互换使用。
填充接口以查看其是否正常工作
interface IModuleProperties {
name: string;
}
interface IModuleState {
index: number;
}
class AnItem1 {
constructor(options: AnItemOptions, somethingElse: SomethingElse) {}
}
class AnItem2 {
constructor(somethingElse: SomethingElse, options: AnItemOptions) {}
}
class AnItem3 {
constructor(somethingElse: SomethingElse) {}
}
const item1: UnaryConstructor<AnItem1, AnItemOptions> = AnItem1;
// error
const item2: UnaryConstructor<AnItem2, AnItemOptions> = AnItem2;
const item3: UnaryConstructor<AnItem3, AnItemOptions> = AnItem3;
游乐场