[英]Use argument's property as type in typescript
I want to assign type to property of class that depends on passed property in argument.我想将类型分配给 class 的属性,这取决于参数中传递的属性。 I wonder if it's possible.
我想知道这是否可能。
Example:例子:
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
}
}
One thing you can do is make your class generic in E
, the type of the c
property, and give b
a lookup type like MappedTypes[E]
.您可以做的一件事是在
E
中使您的 class 成为通用的,即c
属性的类型,并为b
提供一个查找类型,例如MappedTypes[E]
。 This is the closest I can get to the code you're writing now:这是我能得到的最接近您现在正在编写的代码的代码:
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
}
}
Beware though that once you use a generic like this you might find it difficult inside the implementation of MyClass
to use b
and c
in a correlated way.请注意,一旦您使用这样的泛型,您可能会发现在
MyClass
的实现中很难以相关方式使用b
和c
。 See microsoft/TypeScript#13995 and microsoft/TypeScript#24085 for more information.有关详细信息,请参阅microsoft/TypeScript#13995和microsoft/TypeScript#24085 。
Another way to proceed here is to keep b
and c
bundled into a single params
property of a discriminated union type, like this:此处进行的另一种方法是将
b
和c
捆绑到可区分联合类型的单个params
属性中,如下所示:
type Params = { [K in MyEnum]: { a: string, b: MappedTypes[K], c: K } }[MyEnum]
If you examine Params
you'll see that it evaluates to the following union:如果您检查
Params
,您会发现它的计算结果为以下联合:
/*
type Params =
{ a: string; b: Y; c: MyEnum.g; } |
{ a: string; b: X; c: MyEnum.f; } |
{ a: string; b: Z; c: MyEnum.h; }
*/
And then you could define MyClass
like this:然后你可以这样定义
MyClass
:
class MyClassU {
constructor(public params: Params) { }
}
So instead of this.b
you'd need to refer to this.params.b
, which might be annoying.因此,您需要参考
this.params.b
而不是this.b
,这可能很烦人。 On the plus side, you will be able to do things like switch
on this.params.c
and the compiler will understand that it has an implication for the type of this.params.b
:从好的方面来说,您将能够执行诸如
switch
this.params.c
之类的操作,编译器将理解它对this.params.b
的类型有影响:
someMethod() {
switch (this.params.c) {
case (MyEnum.f): {
this.params.b; // known to be X
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.