代码之家  ›  专栏  ›  技术社区  ›  Andrei Андрей Листочкин

引用对象的属性名和值对类型的正确方法是什么?

  •  2
  • Andrei Андрей Листочкин  · 技术社区  · 7 年前

    假设我有一个具有不同类型属性的对象。在TypeScript中,是否有一种方法可以让泛型函数对给定的键和对象值执行操作?

    这里有一个例子。我有个东西 s

    interface Struct {
      a: string
      b: boolean
      c: string
    }
    
    const s: Struct = {
      a: 'hello',
      b: false,
      c: 'world',
    }
    

    假设我有一个函数,它对其中一个属性执行某些操作:

    function makeSetter<K, V>(name: K): (value: V) => void {
      return (value) => s[name] = value;
    }
    

    如何参数化类型 K V 所以为了 makeSetter('a') 我会得到一个类型的函数 (value: string) => void 为了 makeSetter('b') 我会收到一个类型的函数 (value: boolean) => void ?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Gerrit0    7 年前

    这里的技巧是使用通用约束。 K 一定是 keyof Struct V 必须可转让给 Struct[K] . TypeScript docs

    interface Struct {
      a: string
      b: boolean
      c: string
    }
    
    const s: Struct = {
      a: 'hello',
      b: false,
      c: 'world',
    }
    
    function makeSetter<K extends keyof Struct, V extends Struct[K]>(name: K): (value: V) => void {
      return (value) => s[name] = value;
    }
    
    // Helpers for type "unit tests"
    type Equal<T, U> = [T] extends [U] ? [U] extends [T] ? true : false : false
    function assertTrue<T extends true>() {}
    
    const a = makeSetter('a')
    const b = makeSetter('b')
    
    assertTrue<Equal<typeof a, (value: string) => void>>() // No error
    assertTrue<Equal<typeof b, (value: boolean) => void>>() // No error
    
        2
  •  0
  •   Shaun Luttin    7 年前

    通过 Gerrit0 是有用的。下面是第二个有用的方法( that is also in the playground ).

    function makeSetter<K extends keyof Struct>(name: K): (value: Struct[K]) => void {
      return value => (s[name] = value);
    }
    
    const setter1 = makeSetter("a")("foo");
    const setter2 = makeSetter("b")("foo"); // error
    const setter3 = makeSetter("c")(false);
    

    keyof T T[K] . 两者都在标题下描述 Index Types 在高级类型文档中。

    推荐文章