字典 - TypeScript 指定 Map 的值类型但不指定键类型
我想在一个映射上强制执行通用类型,使得每个键的每个值都是特定类型(在此示例中为 A),但我不想覆盖底层默认的键类型。在下面的示例中,如果我将 MY_MAP 的类型指定为 Record<string, A>,MyMapKeys 类型会从期望的键联合 'unknown' | 'error' 变为 string。如何在强制映射的通用值类型为 A 的同时保留 MY_MAP 的只读键?
type A = {
name: string;
description: string;
};
// MY_MAP must be a map of readonly string keys and type A values
const MY_MAP = {
unknown: {
name: 'unknown',
description: 'unknown',
},
error: {
name: 'error',
// should display error: missing property "description"
},
} as const;
// I want the following to be 'unknown' | 'error' not string
type MyMapKeys = keyof typeof MY_MAP;
答案#1
Typescript 4.9(截至 2022 年 10 月 5 日目前处于测试版)
这有一个新功能,称为 satisfies 运算符。
这允许你声明一个受类型约束的值,并且可以被推断为更具体的类型。
const MY_MAP = {
unknown: {
name: 'unknown',
description: 'unknown',
},
error: {
name: 'error',
},
} as const satisfies Record<string, A>;
// Type '{ readonly unknown: { readonly name: "unknown"; readonly description: "unknown"; }; readonly error: { readonly name: "error"; }; }' does not satisfy the expected type 'Record<string, A>'.
// Property 'error' is incompatible with index signature.
// Property 'description' is missing in type '{ readonly name: "error"; }' but required in type 'A'.(1360)
查看游乐场
在 Typescript 4.8 或更低版本中
对此一直的解决方法是使用一个通用的身份函数。
function makeMap<T extends Record<string, A>>(map: T): T {
return map
}
// MY_MAP must be a map of readonly string keys and type A values
const MY_MAP = makeMap({
unknown: {
name: 'unknown',
description: 'unknown',
},
error: {
// Property 'description' is missing in type '{ name: string; }' but required in type 'A'.(2741)
name: 'error',
},
});
查看游乐场
