[英]Argument of function is a property that exists in a type of Typescript
[英]Use argument's property as type in typescript
我想將類型分配給 class 的屬性,這取決於參數中傳遞的屬性。 我想知道這是否可能。
例子:
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
}
}
您可以做的一件事是在E
中使您的 class 成為通用的,即c
屬性的類型,並為b
提供一個查找類型,例如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
和c
。 有關詳細信息,請參閱microsoft/TypeScript#13995和microsoft/TypeScript#24085 。
此處進行的另一種方法是將b
和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.params.b
而不是this.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.