rad*_*man 1 javascript generics typescript
我想在TypeScript中创建一个函数,该函数接受构造函数的数组并返回相应的实例数组。请参见下面的代码。
请注意,该getArray方法非常不正确,仅是传达我的意图的一种尝试。
这可能是任何形式还是超出TypeScript的类型引擎的能力?
class T1 {}
class T2 {}
class T3 {}
type AnyCon = new() => any;
function getOne<T_Con extends AnyCon>(con: T_Con): InstanceType<T_Con> {
return new con();
}
function getArray<T_Cons>(cons: T_Cons): InstanceType<T_Cons>[] {
return cons.map( (c: con) => new con() );
}
let t1: T1 = getOne(T1);
let [t2, t3]: [T2, T3] = getArray( [T2, T3] );
Run Code Online (Sandbox Code Playgroud)
您可以在TS3.1及更高版本中使用映射的数组/元组类型执行此操作。它更容易获得元组推断其余的参数比它是阵列参数,所以我会证明来代替:
function getVariadic<T extends Array<AnyCon>>(...cons: T): {
[K in keyof T]: T[K] extends AnyCon ? InstanceType<T[K]> : never
};
function getVariadic(...cons: AnyCon[]): any[] {
return cons.map((c: AnyCon) => new c());
}
let [t2, t3]: [T2, T3] = getVariadic(T2, T3);
Run Code Online (Sandbox Code Playgroud)
我认为这符合您的预期。希望能有所帮助。祝好运!
编辑:如果您确实需要使用数组来执行此操作,则可以轻松键入该函数,但以将数组的顺序保留为元组的方式来调用它会更加困难:
function getArray<T extends Array<AnyCon>>(cons: T): {
[K in keyof T]: T[K] extends AnyCon ? InstanceType<T[K]> : never
};
function getArray(cons: AnyCon[]): any[] {
return cons.map((c: AnyCon) => new c());
}
// error, getArray([T2, T3]) returns (T2 | T3)[]!
let [t2, t3]: [T2, T3] = getArray([T2, T3]); //
Run Code Online (Sandbox Code Playgroud)
糟糕,我们再试一次
// okay, but verbose and redundant
let [t2, t3]: [T2, T3] = getArray([T2, T3] as [typeof T2, typeof T3]); //
Run Code Online (Sandbox Code Playgroud)
好吧,也许我们可以使用辅助函数来[T2, T3]推断为元组类型:
// put this in a library somewhere
type Lit = string | number | boolean | undefined | null | void | {};
const tuple = <T extends Lit[]>(...args: T) => args;
// works! but now is very similar to getVariadic
let [t2, t3]: [T2, T3] = getArray(tuple(T2, T3));
Run Code Online (Sandbox Code Playgroud)
最后,一旦TypeScript 3.4登陆,将有一些const上下文,该上下文要容易一些,但需要对getArray()以下内容进行一些更改:
// note the widening to ReadonlyArray
function getArray<T extends ReadonlyArray<AnyCon>>(cons: T): {
-readonly [K in keyof T]: T[K] extends AnyCon ? InstanceType<T[K]> : never
};
function getArray(cons: AnyCon[]): any[] {
return cons.map((c: AnyCon) => new c());
}
// works and is the least repetitive
let [t2, t3]: [T2, T3] = getArray([T2, T3] as const);
Run Code Online (Sandbox Code Playgroud)
但是,正如我上面所说,getVariadic()这可能是目前实现此行为的最直接方法。
| 归档时间: |
|
| 查看次数: |
1190 次 |
| 最近记录: |