首页 > 解决方案 > 缩小映射类型值类型

问题描述

用例如下:

首先,我有一个接口,称为Test1在某个键和类型之间进行映射。接下来,我有第二个接口 ,Test2它在这些相同的键和不同的类型之间进行映射。mapper第三,我有知道如何在第一个到第二个之间映射的函数(作为对象中的值)。

本质上,用例是需要在通过某个键连接的不同对象之间进行映射,但要使其尽可能通用,同时受保存映射的接口的约束。

以下代码

interface Test1 {
  a: number;
  b: string;
}

interface Test2 {
  a: object;
  b: Array<number>;
}

type Mapper = {
  [P in keyof Test1]: (param: Test2[P]) => Test1[P];
};

const mapper: Mapper = {
  a: (param: object) => 123,
  b: (param: Array<number>) => 'asd'
};

function test<T extends keyof Test1>(type: T, msg: Test2[T]): Test1[T] {
  const func = mapper[type];
  return func(msg);
}

尝试传递msg给时抛出以下异常func

Argument of type `Test2[T]` is not assignable to parameter of type `number[]`.

在此示例中,假设type将等于'a',然后我想接收mapper作为键值保存的函数并在我拥有'a'的上使用它。msg

我在寻找解决方案时确实看到了这个问题,但我想我的情况可能是不同的,原因是我使用的是映射类型。

有什么办法解决这个问题吗?谢谢!

标签: typescriptgenericsmapped-types

解决方案


问题源于这样一个事实,即func推断的类型(param: object & number[]) => 'number | string'缩小到(param: number[]) => 'number | string'打字稿编译器根本不够聪明,无法意识到参数签名func总是匹配Test2[T]

不幸的是,您最好的解决方案可能只是强制转换并告诉编译器您更了解。

function test<T extends keyof Test1>(type: T, msg: Test2[T]): Test1[T] {
  const func = mapper[type] as any;
  return func(msg);
}

推荐阅读