【问题标题】:Key and value types in TypeScriptTypeScript 中的键和值类型
【发布时间】:2019-04-05 09:09:24
【问题描述】:
interface A { a?: number };
interface B { a?: string };

function copy<
    Source extends object,
    Destination extends { [destinationKey in keyof Source]?: (1) }
>(
    source: Source,
    key: keyof Source,
    destination: Destination,
    transformer: (value: (2)) => (3) 
) {
    if (source[key] !== undefined) {
        destination[key] = transformer ? transformer(source[key]) : source[key];
    }
}

const a: A = { a: 123 };
const b: B = {};

copy(a, "a", b, (value) => value.toString());

在上面的例子中,我可以为以下占位符使用什么:

  • (1) - Destination 中的值类型与 Source 中的相应键相关联。
  • (2) - Source 中的值类型,与参数key 指定的键相关联。
  • (3) - Destination 中的值类型,与参数 key 指定的键相关联。

【问题讨论】:

    标签: typescript generics types typescript3.0


    【解决方案1】:

    您需要一个额外的类型参数来表示将要传入的实际键。此参数将根据传入key 参数的值推断为字符串文字类型。使用这种新类型,我们可以使用类型查询来获取 SourceDestination 类型中的特定属性。

    此外,由于我们只关心特定的 K 键,因此我们可以在将 Destination 类型定义为具有它时使用它(而不是指定 Destination 必须具有 Source 的所有键)。由于我们并不真正关心目标属性的类型,只是它存在并且transformer 函数必须返回与此属性相同类型的值,我们可以在Destination 中指定属性的类型作为unknown

    interface A { a?: number };
    interface B { a?: string };
    
    function copy<
        K extends keyof Source, // The extra type parameter
        Source extends object,
        Destination extends { [destinationKey in K]?: unknown } // Can be anything we don't really care, we only care about the K key existing
    >(
        source: Source,
        key: K, // The key is of type K
        destination: Destination,
        transformer: (value: Source[K]) => Destination[K] // We use K to specify the relation between Source and Destination property type
    ) {
        if (source[key] !== undefined) {
            destination[key] = transformer ? transformer(source[key]) : source[key];
        }
    }
    
    const a: A = { a: 123 };
    const b: B = {};
    
    copy(a, "a", b, (value) => value.toString());
    copy(a, "a", b, (value) => value); /// error
    

    【讨论】:

      猜你喜欢
      • 2019-05-08
      • 2021-06-01
      • 2017-08-08
      • 2021-01-18
      • 1970-01-01
      • 1970-01-01
      • 2016-01-13
      • 2018-09-08
      • 1970-01-01
      相关资源
      最近更新 更多