对于缩小属性的类型,简单的extend 效果很好,如Nitzan's answer:
interface A {
x: string | number;
}
interface B extends A {
x: number;
}
为了扩大,或一般覆盖类型,你可以做Zskycat's solution:
interface A {
x: string
}
export type B = Omit<A, 'x'> & { x: number };
但是,如果您的接口A 扩展了一个通用接口,那么在使用Omit 时,您将失去A 剩余属性的自定义类型。
例如
interface A extends Record<string | number, number | string | boolean> {
x: string;
y: boolean;
}
export type B = Omit<A, 'x'> & { x: number };
let b: B = { x: 2, y: "hi" }; // no error on b.y!
原因是,Omit 在内部只遍历 Exclude<keyof A, 'x'> 键,在我们的例子中这将是一般的 string | number。因此,B 将变为 {x: number; } 并接受 number | string | boolean 类型的任何额外属性。
为了解决这个问题,我想出了一个不同的OverrideProps 实用程序类型,如下所示:
type OverrideProps<M, N> = { [P in keyof M]: P extends keyof N ? N[P] : M[P] };
例子:
type OverrideProps<M, N> = { [P in keyof M]: P extends keyof N ? N[P] : M[P] };
interface A extends Record<string | number, number | string | boolean> {
x: string;
y: boolean;
}
export type B = OverrideProps<A, { x: number }>;
let b: B = { x: 2, y: "hi" }; // error: b.y should be boolean!