我想为依赖于参数传递的属性的类的属性分配类型。我想知道是否有可能。
示例:
enum MyEnum {
g,
f,
h,
}
interface MappedTypes {
[MyEnum.f]: X
[MyEnum.g]: Y
[MyEnum.h]: Z
}
class MyClass {
a: string // does not matter
b: something like MappedTypes[c]
c: MyEnum
constructor(params: { a: string; b: MappedTypes[<inherit from c>]; c: MyType }) {
// for example
// if c === MyEnum.g
// b must be Y as mapped in MappedTypes
}
}
答案 0 :(得分:2)
您可以做的一件事是在E
中将类generic设置为c
属性的类型,并给b
一个lookup type,例如{ {1}}。这是我现在所写代码中最接近的代码:
MappedTypes[E]
请注意,一旦使用了类似的泛型,您可能会发现在class MyClass<E extends MyEnum> {
a: string
b: MappedTypes[E]
c: E
constructor(params: { a: string; b: MappedTypes[E]; c: E }) {
this.a = params.a;
this.b = params.b;
this.c = params.c
}
}
的实现中很难以关联的方式使用MyClass
和b
。有关更多信息,请参见microsoft/TypeScript#13995。
进行此操作的另一种方法是将c
和b
捆绑成discriminated union类型的单个c
属性,如下所示:
params
如果您检查type Params = { [K in MyEnum]: { a: string, b: MappedTypes[K], c: K } }[MyEnum]
,则会发现它的计算结果为以下并集:
Params
然后您可以像这样定义/*
type Params =
{ a: string; b: Y; c: MyEnum.g; } |
{ a: string; b: X; c: MyEnum.f; } |
{ a: string; b: Z; c: MyEnum.h; }
*/
:
MyClass
因此,您需要引用class MyClassU {
constructor(public params: Params) { }
}
而不是this.b
,这可能很烦人。从好的方面来说,您将可以在this.params.b
上进行类似switch
的操作,并且编译器将了解它与this.params.c
的类型有关:
this.params.b
好的,希望其中之一能有所帮助;祝你好运!