题目
中文
实现一个ReplaceKeys
类型, 这个类型可以替换联合类型中指定属性的类型, 如果联合类型中的某个类型没有这个属性, 那就跳过; ReplaceKeys
接受 3 个泛型参数.
例如:
type NodeA = {
type: 'A';
name: string;
flag: number;
};
type NodeB = {
type: 'B';
id: number;
flag: number;
};
type NodeC = {
type: 'C';
name: string;
flag: number;
};
type Nodes = NodeA | NodeB | NodeC;
type ReplacedNodes = ReplaceKeys<
Nodes,
'name' | 'flag',
{ name: number; flag: string }
>; // {type: 'A', name: number, flag: string} | {type: 'B', id: number, flag: string} | {type: 'C', name: number, flag: string} // would replace name from string to number, replace flag from number to string.
type ReplacedNotExistKeys = ReplaceKeys<Nodes, 'name', { aa: number }>; // {type: 'A', name: never, flag: number} | NodeB | {type: 'C', name: never, flag: number} // would replace name to never
English
Implement a type ReplaceKeys, that replace keys in union types, if some type has not this key, just skip replacing,
A type takes three arguments.
For example:
type NodeA = {
type: 'A';
name: string;
flag: number;
};
type NodeB = {
type: 'B';
id: number;
flag: number;
};
type NodeC = {
type: 'C';
name: string;
flag: number;
};
type Nodes = NodeA | NodeB | NodeC;
type ReplacedNodes = ReplaceKeys<
Nodes,
'name' | 'flag',
{ name: number; flag: string }
>; // {type: 'A', name: number, flag: string} | {type: 'B', id: number, flag: string} | {type: 'C', name: number, flag: string} // would replace name from string to number, replace flag from number to string.
type ReplacedNotExistKeys = ReplaceKeys<Nodes, 'name', { aa: number }>; // {type: 'A', name: never, flag: number} | NodeB | {type: 'C', name: never, flag: number} // would replace name to never
答案
type ReplaceKeys<
U extends object,
T extends string,
Y extends object
> = U extends U
? {
[P in keyof U]: P extends T
? P extends keyof Y
? Y[P]
: never
: U[P];
}
: never;
标签:Typescript,name,number,flag,体操,type,string,ReplaceKeys
From: https://www.cnblogs.com/laggage/p/type-challenge-replace-keys.html