代码之家  ›  专栏  ›  技术社区  ›  Rico Kahler

在typescript中,可以使用泛型添加属性键?

  •  1
  • Rico Kahler  · 技术社区  · 6 年前

    在typescript中,可以使用泛型添加属性键吗?

    function f<T extends string>(k: T) {
      return { [k]: 'test'; };
    }
    
    const obj = f('foo');
    // some how assert that obj.foo exists
    

    我有一个上面的函数,它接受一把钥匙 k 并使用 {[identifier]: 'value'} .


    我想知道是否可以捕获字符串文字类型,例如。 'some-key' / T extends string 并在另一个类型中使用文本。像这样:

    interface F<T extends string> {
      [T]: SomeRandomType;
      otherKey: string;
      anotherKey: number;
    }
    
    interface SomeRandomType { /* ... */ }
    
    const f: F<'bar'> = /* ... */;
    f.otherKey; // should work
    f.anotherKey; // should work
    f.bar; // should work
    

    有什么想法吗?这不可能吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Benjamin Hodgson    6 年前

    是的,这是可能的,使用一个创造性的组合 mapped types intersection types

    您可以使用映射类型为“任意字符串文本键控属性”案例建模。

    type F<Keys extends string> = {
        [K in Keys] : number;
    }
    
    const f : F<'bar'> = null;
    f.bar;  // typed as a number
    f.wibble;  // type error
    

    注意,映射类型必须 type 声明,不是 interface 别问我有什么区别!

    然后是使用交集类型操作符在顶部分层附加属性的情况。 & . 因为某些原因你不得不使用 & 为了这个。似乎不允许将这些属性声明为同一对象类型的一部分。

    type F<Keys extends string> = {
        [K in Keys] : number;
    } & {
        additionalKey1 : object;
        additionalKey2 : string;
    }
    const f : F<'bar'> = null;
    f.bar;  // typed as a number
    f.additionalKey1;  // typed as an object