我在下面的例子中去掉了很多代码,但是应该是同样的精神。
您缺少的功能称为
mapped arrays/tuples
计划于年发布
TypeScript 3.1
2018年8月的某个时候。您将能够像映射其他类型一样映射数组和元组,如下所示:
type Mapped<T> = {[K in keyof T]: Array<T[K]>};
type Example = Mapped<[string, number, boolean]>;
// type Example = [string[], number[], boolean[]];
如果你用
typescript@next
现在你可以试试。
在你的情况下
希望
做的事情就像
type MappedArgs = {[K in keyof TArgs]: TProps[TArgs[K]]};
type ConstructorType = new (...args: MappedArgs) => any;
但有几个突出的问题阻止你这么做。一是由于某种原因编译器还不明白
TArgs[K]
是的有效索引
TProps
. 所以你可以介绍
conditional type
这样你就可以解决这个问题:
type Prop<T, K> = K extends keyof T ? T[K] : never;
type MappedArgs = {[K in keyof TArgs]: Prop<TProps,TArgs[K]>};
但以下方法仍然不起作用:
type ConstructorType = new (...args: MappedArgs) => any;
// error, a rest parameter must be of an array type
隐马尔可夫模型,
MappedArgs
当然是数组类型,但TypeScript没有意识到这一点。这也不能让人信服:
type MappedArgs = {[K in keyof TArgs]: Prop<TProps,TArgs[K]>}
& unknown[]; // definitely an array!
type ConstructorType = new (...args: MappedArgs) => any;
// error, a rest parameter must be of an array type
这似乎是
outstanding bug
在映射的数组/元组中,映射的类型在任何地方都不被视为数组。这可能会在TypeScript3.1的发行版中得到修复。现在,您可以通过添加一个新的伪类型参数来解决问题,如
type Prop<T, K> = K extends keyof T ? T[K] : never;
type MappedArgs = {[K in keyof TArgs]: Prop<TProps,TArgs[K]>}
& unknown[]; // definitely an array!
type ConstructorType<A extends MappedArgs = MappedArgs> = new (...args: A) => any;
这很管用。我们看看能不能测试一下。怎么样:
type Prop<T, K> = K extends keyof T ? T[K] : never;
interface NewMethod<TProps> {
create<TArgs extends Array<Extract<keyof TProps, string>>,
MTArgs extends unknown[] & { [K in keyof TArgs]: Prop<TProps, TArgs[K]> }>(
geometryClass: new (...args: MTArgs) => any,
...args: Array<Extract<keyof TProps, string>>): void;
}
declare const z: NewMethod<{ a: string, b: number }>;
z.create(null! as new (x: string, y: number) => any, "a", "b"); // okay
z.create(null! as new (x: string, y: number) => any, "a", "c"); // error, "c" is bad
z.create(null! as new (x: string, y: boolean) => any, "a", "b"); // error, constructor is bad
他们的行为似乎是你想要的。。。尽管上一个案例中的错误非常模糊,似乎并没有指出问题在于
y
参数是
boolean
不匹配
string
或
number
从
TProps[keyof TProps]
.
不管怎么说,到2018年8月为止,这仍然是一件很有前途的事情,所以我认为你可能需要等一段时间,然后才能确定它到底会如何工作。希望能有所帮助。祝你好运!