【问题标题】:Extend generic interface with strongly typed implementations使用强类型实现扩展通用接口
【发布时间】:2020-03-09 01:30:56
【问题描述】:

我有一个 Transformer 接口:

interface Transformer<K> {
    type: string,
    apply<K>(data: K) : K
}

我想创建 2 个扩展 Transformer 的接口


interface NumberTransformer extends Transformer<number> {
    type: 'number',
    apply<number>(data: number) : number
}

interface StringTransformer extends Transformer<string> {
    type: 'string',
    apply<string>(data: string) : string
}

这会引发 2 个 TS 错误 (TS6133) 'string'/'number' is declared but its value is never read,我不明白为什么

然后,在 Transformer[] 列表中,我希望能够使用 type 参数作为类型保护,例如

const a : DataTransformer<??>[] = [{
    type: 'number',
    apply: (n :number) => n * 10
},
{
    type: 'string',
    apply: (str :string) => str.substr(0,1)
}];

a.forEach(s => {
  if (s.type === 'string')
    //s.apply is string => string type
});

但是我不知道a应该是什么类型? DataTransformer&lt;any&gt;?

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:
    type TransformerKeyType = {
      'number': number,
      'string': string,
    }
    
    interface DataTransformer<T extends keyof TransformerKeyType> {
        type: T,
        apply(data: TransformerKeyType[T]) : TransformerKeyType[T]
    }
    
    type NumberTransformer = DataTransformer<'number'>;
    type StringTransformer = DataTransformer<'string'>;
    
    const a : (DataTransformer<'number'> |  DataTransformer<'string'>)[] = [{
        type: 'number',
        apply: (n) => n * 10
    },
    {
        type: 'string',
        apply: (str) => str.substr(0,1)
    }];
    
    a.forEach(s => {
      if (s.type === 'string') {
        s // here properly we have DataTransformer<'string'>
      }
    });
    

    说明: TransformerKeyType 是一种类型,它为我们提供了字符串和类型之间的关系。所以我们可以轻松地将字符串'number' 映射到类型number

    DataTransformer 作为一个通用参数,它只接受TransformerKeyType 的键,所以只有numberstring。并且类型的主体通过说KTransformerKeyType[T] 自动设置正确的K。所以在TransformerKeyType 中输入给定的属性T

    type NumberTransformer = DataTransformer&lt;'number'&gt;; 是我们类型的实例。它正在正确设置类型为number的应用函数

    (DataTransformer&lt;'number'&gt; | DataTransformer&lt;'string'&gt;)[] 表示我们有一个数组,其中包含带有数字的 DataTransformer 或带有字符串的 DataTransformer。它工作得很好,因为您不需要在 apply 函数中声明参数类型,并且您可以离开 n =&gt; n * 10 其中类型称为数字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 1970-01-01
      • 2012-10-08
      • 1970-01-01
      相关资源
      最近更新 更多