TypeScript 如何重写接口的属性类型
type Old = Other & {rewrite:number};
type New = Old & {rewrite:string};
预期行为:
New 的类型:Other & {rewrite:string}
实际行为:
New 的类型:Other & {rewrite:string & number}
答案#1
这是交叉类型的设计行为。如果该属性存在于交叉类型的两个成员上,则生成的属性类型将是原始类型的交叉类型。
要替换一个属性,我们可以首先使用 Pick 和 Exclude 将其从原始类型中排除:
type Omit<T, TKey extends keyof T> = Pick<T, Exclude<keyof T, TKey>>
type Other = { a: number };
type Old = Other & {rewrite:number};
type New = Omit<Old, 'rewrite'> & {rewrite:string};
let n: New;
n.rewrite // string
n.a // number
如果这是一个常见的场景,我们甚至可以创建一个通用类型来进行替换:
type Omit<T, TKey extends keyof T> = Pick<T, Exclude<keyof T, TKey>>
type Other = { a: number };
type Old = Other & {rewrite:number, rewrite2:number};
type Replace<T, TKey extends keyof T, TKeyType> = Omit<T, TKey> & Record<TKey, TKeyType>
type New = Replace<Old, 'rewrite', string> // replace one
type New2 = Replace<Old, 'rewrite' | 'rewrite2', string> // replace more
