为什么下面的示例无法编译?

function mapObjectValues<I, O, K extends keyof any>(obj: Record<K, I>, map: (value: I, key: K) => O): Record<K, O>
function mapObjectValues<K extends keyof any, I extends Record<K, any>, O extends Record<K, any>>(obj: I, map: (value: I[K], key: K) => O[K]): O
function mapObjectValues<I, O>(obj: Record<keyof any, I>, map: (value: I, key: keyof any) => O): Record<keyof any, O>
function mapObjectValues<I, O>(_obj: Record<keyof any, I>, _map: (value: I, key: keyof any) => O): Record<keyof any, O> {
    throw "not relevant"
}

function checker(_input: Record<string, string>) { }

// compiles
checker(mapObjectValues({
    foo: "bar"
}, (_, k) => k))

// compiles
checker(mapObjectValues({
    ["foo"]: "bar"
}, (_, k) => k))

// fails with:
//
// Argument of type 'Record<string | number, string | number>' is not assignable to parameter of type 'Record<string, string>'.
//   'string' index signatures are incompatible.
//     Type 'string | number' is not assignable to type 'string'.
//       Type 'number' is not assignable to type 'string'.
checker(mapObjectValues({
    [{
        foo: "foo"
    }.foo]: "bar"
}, (_, k) => k))

// compiles
checker(mapObjectValues({
    [({
        foo: "foo"
    } as const).foo]: "bar"
}, (_, k) => k))

Playground

这是当前打字脚本中的类型推理的限制吗?

推荐答案

这是由于keyof个索引类型返回number | string个.

type foo = keyof { [x: string]: string; }
//   ^? type foo = number | string

在Typescript GH上每this issue个,它就能按预期工作.

Typescript相关问答推荐

类型脚本不会推断键的值类型

从接口创建类型安全的嵌套 struct

动态判断TypScript对象是否具有不带自定义类型保护的键

React router 6.22.3不只是在生产模式下显示,为什么?

typescribe警告,explate—deps,useEffect依赖项列表

更新为Angular 17后的可选链运算符&?&问题

如何在TypeScrip中使用嵌套对象中的类型映射?

状态更新后未触发特定元素的Reaction CSS转换

如何使用Zod使一个基于其他字段值的字段为必填字段?

如何使用WebStorm调试NextJS的TypeScrip服务器端代码?

使用Dockerfile运行Vite React应用程序时访问env变量

如何 bootstrap TS编译器为类型化属性`T`推断正确的类型?

从类型脚本中元组的尾部获取第n个类型

如何在Angular /字体中访问API响应的子元素?

如何填写Partial的一些属性并让类型系统知道它?

如何为对象数组中的每个条目推断不同的泛型

Typescript循环函数引用

我应该使用服务方法(依赖于可观察的)在组件中进行计算吗?

如何在由函数参数推断的记录类型中具有多个对象字段类型

在 TypeScript 中实现类型级别深度优先搜索