网站搜索

typescript - 更严格的类型不能赋值给更宽松的类型吗?


const func: (prm: Record<string, string | number>) => void = (prm) => {
    return;
};

interface Obj {
    key1: string;
}

func({ key1: 'value1' } as Obj); // Argument of type 'Obj' is not assignable to parameter of type 'Record<string, string | number>'. Index signature for type 'string' is missing in type 'Obj'.ts(2345)

为什么 Obj 对象不能作为函数 func 的输入,而 Obj 却可以满足 prm 所需的数据形状?

答案#1

应用程序失败,因为类型为 Record<string, string | number> 的对象应当为任何 string 键提供 string | number 类型的值,而 Obj 并非如此。

例如,考虑这个类型正确的 func 定义:

const func: (prm: Record<string, string | number>) => void = (prm) => {
  const v = prm.someProp
  console.log(v.toLocaleString())
};

鉴于prm的类型,属性prm.someProp应该存在(并且它应该有一个toLocaleString方法,就像string和number一样)。然而,如果你用一个Obj参数调用func,它将在运行时失败:

func({ key1: 'value1' } as any); // Runtime error

你可以通过将 func 设为泛型来获取所需的类型:

const func: <K extends string>(prm: Record<K, string | number>) => void = (prm) => {
  return
};

interface Obj {
  key1: string;
}

func({ key1: 'value1' } as Obj); // No type error

TypeScript 游乐场