typescript 泛型与内置 Record 使用问题 ?

默认使用 Record 的例子
内置 Record 会遍历 CatName 联合类型,每个字面量类型的值是 CatInfo 类型

interface CatInfo {
  age: number;
  breed: string;
}
type CatName = "miffy" | "boris" | "mordred";
const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 8, breed: "Maine Coon" },
  mordred: { age: 16, breed: "Brittish Shorthair" },
};

使用泛型的另一个例子
在调用say函数时并没有传递泛型,ts会自动将泛型T设置为 string

function say<T>(arg: T) {
  console.log(arg)
}
say('abc')

请问在下面这个例子中为什么会自动将对象字面量的key和value拆开传递到 Record 中?
我个人理解是使用函数的时候没有主动传递泛型,ts内部会使用函数调用时参数的值做为类型,但 Record 需要 2 个泛型,对象字面量只有一个类型,这块的运行机制是?

function fn<K extends keyof any, V>(o: Record<K, V>) {
  console.log(o);
}

fn({ name: "zhangsan", age: 666, address: { num: 1 } })

/*
function fn<"name" | "age" | "address", string | number | {
    num: number;
}>(o: Record<"name" | "age" | "address", string | number | {
    num: number;
}>): void
*/
阅读 2.7k
1 个回答

{ name: "zhangsan", age: 666, address: { num: 1 } } 的键和值类型集分别是:

  • 键类型:"name" | "age" | "address"
  • 值类型:string | number | { num: string }

所以它作为一个对象的类型,去匹配 Record<K, V> 的话,就是

  • type K = "name" | "age" | "address"
  • type V = string | number | { num: string }

这是 TypeScript 推导出来的:通过参数的类型,按其兼容性和函数声明的参数类型进行推导找出来的。

推荐问题
logo
Microsoft
子站问答
访问
宣传栏