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

Javascript 使用参数';属性作为typescript中的类型,javascript,typescript,types,Javascript,Typescript,Types,我想将类型分配给依赖于参数中传递的属性的类的属性。我想知道这是否可能 例如: 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:

我想将类型分配给依赖于参数中传递的属性的类的属性。我想知道这是否可能

例如:

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  
    }
}
enum MyEnum{
G
F
H
}
接口映射类型{
[MyEnum.f]:X
[髓鞘g]:Y
[MyEnum.h]:Z
}
类MyClass{
答:字符串//不重要
b:有点像MappedTypes[c]
c:髓鞘
构造函数(参数:{a:string;b:MappedTypes[];c:MyType}){
//比如说
//如果c==MyEnum.g
//b必须是映射在MappedTypes中的Y
}
}

您可以做的一件事是将类设置为
E
,即
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
    }
}
如果检查
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

type Params = { [K in MyEnum]: { a: string, b: MappedTypes[K], c: K } }[MyEnum]
class MyClassU {
    constructor(public params: Params) { }
}
因此,您需要参考
this.params.b
,而不是
this.b
,这可能会很烦人。另一方面,您将能够在
this.params.c
上执行
切换
之类的操作,并且编译器将理解它对
this.params.b
的类型有影响:

    someMethod() {
        switch (this.params.c) {
            case (MyEnum.f): {
                this.params.b; // known to be X
            }
        }
    }


您可以做的一件事是将类设置为
E
,即
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
    }
}
如果检查
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

type Params = { [K in MyEnum]: { a: string, b: MappedTypes[K], c: K } }[MyEnum]
class MyClassU {
    constructor(public params: Params) { }
}
因此,您需要参考
this.params.b
,而不是
this.b
,这可能会很烦人。另一方面,您将能够在
this.params.c
上执行
切换
之类的操作,并且编译器将理解它对
this.params.b
的类型有影响:

    someMethod() {
        switch (this.params.c) {
            case (MyEnum.f): {
                this.params.b; // known to be X
            }
        }
    }