简体   繁体   English

使用参数的属性作为 typescript 中的类型

[英]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的实现中很难以相关方式使用bc See microsoft/TypeScript#13995 and microsoft/TypeScript#24085 for more information.有关详细信息,请参阅microsoft/TypeScript#13995microsoft/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:此处进行的另一种方法是将bc捆绑到可区分联合类型的单个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
            }
        }
    }

Playground link to code 游乐场代码链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 function 的参数是存在于 Typescript 类型中的属性 - Argument of function is a property that exists in a type of Typescript Typescript Generics:使用 output 参数类型来构建输入参数类型 - Typescript Generics: Use output argument type to build input argument type 什么打字稿类型用于函数参数? - What typescript type use for function argument? Typescript - 使用数组参数中的元素作为返回类型 - Typescript - Use element in array argument as return type 如何根据Typescript中的字符串参数定义函数的参数类型? - How to define a function's argument type dependent on string argument in Typescript? 可以使用对象属性作为方法的参数 - Possible to use an object property as a method's argument TypeScript:类型参数不可分配 - TypeScript: Argument of type is not assignable 是否可以将构造函数用作TypeScript中另一个函数的参数类型? - Is it possible to use a constructor function as a type of an argument of another function in TypeScript? 在 Typescript 中,是否可以在不覆盖值的情况下覆盖超类属性的类型? - In Typescript, is it possible to override a superclass property's type without overriding the value? 如何在 TypeScript 中使用嵌套对象? 类型“对象”上不存在属性 - How to use nested objects in TypeScript? Property does not exist on type 'object'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM