代码之家  ›  专栏  ›  技术社区  ›  Lukas

TypeScript:泛型,是任何普通对象

  •  1
  • Lukas  · 技术社区  · 5 年前

    以下是我解释问题的实际代码:

    https://gist.github.com/LukasBombach/7bf255392074509147a250b448388518

    我想用TypeScript指定一个泛型,它是普通对象的任何数据结构

    class MyClass<T extends {}> {
      public vars: T;
    
      constructor() {
        this.vars = {};
      }
    }
    

    所以我能做到

    interface MyType {
      foo: string;
      bar: number;
    }
    
    new MyClass<MyType>()
    

    interface MyType {
      baz: string;
      boo: {
        bam: Function;
        bix: number;
      };
    }
    
    new MyClass<MyType>()
    

    class MyClass<T extends {}> {
      public vars: T;
    
      constructor() {
        this.vars = {};
        //   ^^^^
      }
    }
    
    Type '{}' is not assignable to type 'T'.
      '{}' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint '{}'.ts(2322)
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   Reactgular    5 年前

    定义的类型 vars Partial<T>

    class MyClass<T> {
      public vars: Partial<T>;
    
      constructor() {
        this.vars = {};
      }
    }
    

    可选择的 .

    const x = new MyClass<MyType>();
    
    console.log(x.vars.foo); // prints "undefined" but there is no TS error
    console.log(x.vars.thing); // prints "undefined" but TS error for unknown property.
    

    https://netbasal.com/getting-to-know-the-partial-type-in-typescript-ecfcfbc87cb6

    总是这样 部分 . 执行以下操作时,您将收到警告。

    const x: Partial<FooBar> = {};
    const y: FooBar = x; // TS error, because x is partial.
    

    你可以通过施放强制分配。

    const y: FooBar = x as FooBar;
    

    部分 . 所以它是 你永远不会知道它是否真的被值填充。

    可以使用运行时类型验证程序来检查:

    export function isMyType(value: any): value is MyType {
       return typeof value['foot'] === 'string'
              && typeof value['bar'] === 'number';
    }
    
    const x: Partial<MyType> = {};
    
    if(isMyType(x)) {
        const y: MyType = x; // there is no TS, because of the isMyType check
    }
    

    is 调用TypeScript中的运算符,但在条件内部使用时 类型

    它还为您提供了一个更改,以便在值不是您认为应该的值时抛出运行时错误。

        2
  •  0
  •   MTCoster    5 年前

    这个错误完全合乎逻辑。

    MyType ,相当于 MyClass 没有通用的:

    interface MyType {
      foo: string;
      bar: number;
    }
    
    class MyClass {
      public vars: MyType;
    
      constructor() {
        this.vars = {};
      }
    }
    

    vars 现在一定有 foo bar vars = {} 是不允许的。

        3
  •  0
  •   Trina Choudhury    5 年前

    我想这也许能解决问题

    class MyClass<T extends {[key:string]: any}> {
      public vars: T;
    
      constructor() {
        this.vars = {};
      }
    }
    

    如:

    interface MyType {
      foo: string;
      bar: number;
    }
    let test = new MyClass<MyType>();