[英]Typescript using mapped types with arrays
I'm trying to use mapped types with typescript, which is supposed to be possible, but running into some issues.我正在尝试将映射类型与 typescript 一起使用,这应该是可能的,但遇到了一些问题。
Let's say I have 3 classes:假设我有 3 个课程:
class A {
public foo1 = 1;
}
class B {
public foo2 = 1;
}
class C {
public foo3 = 1;
}
const base = [A, B, C] as const;
Basically, what I want is to pass base
into some function, and get back an array with 3 matching instances.基本上,我想要的是将
base
传递给一些 function,并取回一个包含 3 个匹配实例的数组。
type CTOR = new(...args: any[]) => any
function instantiate1<T extends ReadonlyArray<CTOR>>(arr: T): {[K in keyof T]: T[K]} {
const items = arr.map(ctor => new ctor());
return items as any; //Don't mind about breaking type safety inside the function
}
Now this returns:现在返回:
const result1 = instantiate2(base) //type is [typeof A, typeof B, typeof C]
which makes sense, as I didn't really "map" the type yet, just made sure the syntax works.这是有道理的,因为我还没有真正“映射”类型,只是确保语法有效。
However if I try to actually map the type:但是,如果我尝试实际 map 类型:
function instantiate2<T extends ReadonlyArray<CTOR>>(arr: T): {[K in keyof T]: InstanceType<T[K]>} {
const items = arr.map(ctor => new ctor());
return items as any; //Don't mind about breaking type safety inside the function
}
I get an error that T[K]
doesn't satisfy the constraint of instance type.我收到
T[K]
不满足实例类型约束的错误。
anyone as an idea for a workaround?任何人作为解决方法的想法?
This is a known bug in TypeScript, according to microsoft/Typescript#27995 .根据microsoft/Typescript#27995 ,这是 TypeScript 中的一个已知错误。 It's a fairly old issue now and is on the "Backlog", so I wouldn't expect it to be fixed anytime soon.
这是一个相当老的问题,并且在“积压”中,所以我不希望它很快得到修复。
Workarounds:解决方法:
Explicitly constrain T[K]
to the desired constructor type.将
T[K]
显式约束为所需的构造函数类型。 I usually do this with the Extract<T, U>
utility type like this:我通常使用
Extract<T, U>
实用程序类型来执行此操作,如下所示:
declare function instantiate<T extends ReadonlyArray<Ctor>>(arr: T): {
[K in keyof T]: InstanceType<Extract<T[K], Ctor>>
};
const result = instantiate(base);
// const result: readonly [A, B, C]
Or, you could replace the InstanceType<T>
utility type with your own version that doesn't care if T
is a constructor.或者,您可以将
InstanceType<T>
实用程序类型替换为您自己的版本,该版本不关心T
是否是构造函数。 The existing type definition is: 现有的类型定义是:
type InstanceType<T extends new (...args: any) => any> =
T extends new (...args: any) => infer R ? R : any;
So you can loosen it to:因此,您可以将其放松为:
type MyInstanceType<T> = // no constraint on T
T extends new (...args: any) => infer R ? R : any;
and then your original version works as expected:然后您的原始版本按预期工作:
declare function instantiate<T extends ReadonlyArray<Ctor>>(arr: T): {
[K in keyof T]: MyInstanceType<T[K]>
};
const result = instantiate(base);
// const result: readonly [A, B, C]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.