Для звуження типу власності extend
ідеально підходить просте , як у відповіді Ніцана :
interface A {
x: string | number;
}
interface B extends A {
x: number;
}
Для розширення або взагалі перевизначення типу ви можете зробити рішення Zskycat :
interface A {
x: string
}
export type B = Omit<A, 'x'> & { x: number };
Але якщо ваш інтерфейс A
розширює загальний інтерфейс, ви втратите нестандартні типи властивостей A
, що залишилися при використанні Omit
.
напр
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" };
Причина в тому, що 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" };