如何为构造函数创建一个TypeScript类型,其中一个参数为指定类型,其余参数未指定?



我想创建一个类型,它保证一个类接收特定类型作为其构造函数的第一个参数。给定这些定义,

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); }

不进行类型检查。

你知道为什么类型检查似乎只在构造函数上失效吗?

您的代码运行良好。AnItemOptionsSomethingElse结构相同的,因为它们只是空接口。没有任何区分结构,它们可以互换使用。

填充接口以查看其是否正常工作

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;
游乐场

最新更新