代码之家  ›  专栏  ›  技术社区  ›  Flavien Volken

Typescript:允许泛型类型只能是具有“string”属性的对象

  •  2
  • Flavien Volken  · 技术社区  · 6 年前

    我想知道在TS中是否有可能强制泛型的属性类型。我只允许传递具有“string”属性的对象类型的泛型。例如,如果传递的泛型接口将包含数字或符号属性,则引发错误。

    POC 关于我所尝试和评论的行为:

    class Test<T extends {[key: string]: any}>{
        private data: T;
    
        public getValue<K extends keyof T>(key: K): T[K] {
            return this.data[key];
         }
    }
    
    // the property is a string = ok
    const okay = new Test<{ "aString": string }>();
    
    // the property is a number = should raise an error
    const shouldFail = new Test<{ 0: string }>();
    
    1 回复  |  直到 6 年前
        1
  •  8
  •   Titian Cernicova-Dragomir    6 年前

    如果对象有一个字符串索引,我们也可以按数字索引对象,因此编译器没有理由抛出一个错误数字。这是故意的。

    declare let skeys: { [key: string]: number }
    let v1 = skeys[0] // number 
    let v2 = skeys["0"] // number
    
    declare let nkeys: { [key: number]: number }
    let v3 = nkeys[0] // number 
    let v4 = nkeys["0"] // error 
    
    
    declare let snkeys: {
        [key: number]: number;
        [key: string]: string | number // The string index has to contain any value reuned by the number index
    }
    let v5 = snkeys[0] // number 
    let v6 = snkeys["0"] // string| number 
    

    class Test<T extends { [key: string]: any } & (keyof T extends string ? {} : "T must obnly have string keys") >{
        private data!: T;
    
        public getValue<K extends keyof T>(key: K): T[K] {
            return this.data[key];
        }
    }
    
    // the property is a string = ok
    const okay = new Test<{ "aString": string }>();
    // Error: Type '{ 0: string; }' does not satisfy the constraint '{ [key: string]: any; } & "T must only have string keys"'.
    const shouldFail = new Test<{ 0: string }>();
    

    注意

    如果对的值没有任何其他约束 T 一个简单的 object 类型也可以

    class Test<T extends object & (keyof T extends string ? {} : "T must only have string keys") >{ }