【问题标题】:Type backward referring in TypeScript在 TypeScript 中键入向后引用
【发布时间】:2021-04-29 03:17:24
【问题描述】:

我需要关于包含向后引用的类型声明的帮助,我会解释:

给定一个这样的接口Car

interface Car {
  name: string,
  engine: Engine,
  brand: Brand,
  ...
}

我需要创建一个如下结构的类型:

[ 'engine', (engine1, engine2) => {...} ]

其中engine1engine2Car['engine'] 的类型相同,并且不限于一般性 - 我需要一个数组:

[(keyof T) as S, (s1: S, s2: S) => { ... }]

换句话说:一个包含两个元素的数组:第一个 - 是 T 的属性,第二个是接受 arg1arg2 的函数,其中它们的类型 与类型相同T[the first item in the array]

有人可以帮我声明这样的类型吗?

【问题讨论】:

    标签: javascript typescript typescript-generics


    【解决方案1】:

    这样就可以了:

    type MyType<T extends object> = { [S in keyof T]: [S, (s1: T[S], s2: T[S]) => any] }[keyof T];
    
    const e: MyType<Car> = ['engine', (e1: Engine, e2: Engine) => { }];
    

    解释(由于在评论中要求):

    把它拆开。 考虑类型:

    type MyType1<T extends object, S extends keyof T> = [S, (s1: T[S], s2: T[S]) => any];
    

    这种类型看起来很明显。但有一个缺点 - 您必须明确键入键名。

    const e: MyType1<Car, 'engine'> = ['engine', (e1: Engine, e2: Engine) => { }];
    

    因此,您可以为每个属性键合并所有 MyType1 可能性:

    type MyType2<T extends object> = { [S in keyof T]: MyType1<T, S> }[keyof T];
    

    上面的原始类型只是这两个步骤合二为一;)。

    【讨论】:

    • 优雅 :) 稍微解释一下对未来的读者会有帮助。
    • 看起来不错。不幸的是,我不能投票两次;)
    【解决方案2】:

    也许有更好的方法,但这就是我所拥有的。

    我看不到使用“普通”类型的方法,所以我的建议是创建一个“工厂”——基本上是一个创建这种数组的函数。

    这为创建类型提供了更大的灵活性。

    type Engine = {
      model: number;
    }
    type Brand = {
      name: string;
    }
    
    interface Car {
      name: string;
      engine: Engine;
      brand: Brand;
    }
    
    interface ArrayFactory<T> {
      <U extends keyof T>(prop: U): [U, (arg1: T[U], arg2: T[U]) => void];
    }
    
    const createArray: ArrayFactory<Car> = (prop) => [prop, (arg1, arg2) => console.log(arg1, arg2)];
    
    const arr = createArray('engine');
    console.log(arr[0] === 'engine1');
    arr[1]({model: 1}, {model: 2})
    

    playground

    【讨论】:

      猜你喜欢
      • 2021-03-23
      • 2020-06-25
      • 2020-12-11
      • 2021-09-16
      • 2019-12-25
      • 1970-01-01
      • 1970-01-01
      • 2019-09-21
      • 1970-01-01
      相关资源
      最近更新 更多