我的第一种方法是使用
Partial<Record<keyof Entity, number>>
,但由于某些原因导致出现错误 Type [...] is not assignable to type 'Partial<Record<keyof Entity, number>>'.
。所以我退而求其次,手动编写类型映射
{ [K in keyof Entity]?: number }
,这似乎可行。interface Person {
firstName: string;
lastName: string;
}
export class SomeClass<Entity extends Person> {
protected getFilter(): void {
let prio1: { [K in keyof Entity]?: number };
prio1 = { firstName: 1 };
// Type '{ firstName: 2; }' is not assignable to type 'Partial<Record<keyof Entity, number>>'.
let prio2: Partial<Record<keyof Entity, number>>;
prio2 = { firstName: 2 };
}
}
请问这两种符号有什么区别,为什么内置的Typescript工具无法使用?
在Typescript playground上也可以找到代码片段:请点击此处查看。
我使用的资源包括:记录类型,映射类型,泛型。
更新:
我尝试分解Typescript在内部执行的操作,逐步展开
Partial<Record<keyof Entity, number>>
,并使用官方类型定义进行说明。/**
* Make all properties in T optional
*/
type Partial<T> = { [P in keyof T]?: T[P] };
/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends keyof any, T> = { [P in K]: T };
class SomeClass<Entity extends Person> {
getFilter(): void {
let prio1: { [K in keyof Entity]?: number };
prio1 = { firstName: 1 };
let p1: Partial<Record<keyof Entity, number>>;
let p2: Partial<{ [P in keyof Entity]: number }>;
let p3: { [P2 in keyof { [P1 in keyof Entity]: number }]?: { [P1 in keyof Entity]: number }[P2] };
let p4: { [P2 in keyof Entity]?: { [P1 in keyof Entity]: number }[P2] };
let p5: { [P2 in keyof Entity]?: number };
p1 = { firstName: 3 }; // error
p2 = { firstName: 3 }; // error
p3 = { firstName: 3 }; // error
p4 = { firstName: 3 }; // error
p5 = { firstName: 3 }; // works
}
}
Typescript似乎无法将{ [P1 in keyof Entity]: number }[P2]
中的 P2 in keyof Entity
解析为number
。
toString
的分析:类型() => string
与number
不兼容。 但我不确定这是否是实际的根本原因。事实上,最后一个代码示例仅适用于prio1
,因为它的类型基于Entity
的keyof
而不是User
的keyof
。如果它基于User
,它也会导致Type '() => string' is not assignable to type 'number'.
。 - Elias RablPartial
和Record
TS定义进行解糖的尝试。 - Elias Rabl{ [K in keyof Entity]?: number }
应该等同于Partial<Record<keyof Entity, number>>
,因为后者只是一种简单的语法糖来实现相同的效果。手动分解第二个语句,使用 Typescript 中Partial
和Filter
的内部类型定义,最终得到了预期的类型。但由于某些原因,Typescript 并没有以相同的方式解析它。它应该能够将{ [P1 in keyof Entity]: number }[P2]
简化为number
,因为 Entity 中的所有字段都映射到数字,并且 P2 表示 Entity 的所有键。 - Elias Rabl