Відповіді:
У TypeScript 3.5 Omit
тип було додано до стандартної бібліотеки. Дивіться приклади нижче, як їх використовувати.
У TypeScript 2.8 Exclude
тип був доданий до стандартної бібліотеки, що дозволяє записувати тип опущення просто так:
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
Ви не можете використовувати Exclude
тип у версіях нижче 2.8, але ви можете створити заміну для нього, щоб використовувати той самий тип визначення, як вище. Однак ця заміна працюватиме лише для типів рядків, тому вона не така потужна, як Exclude
.
// Functionally the same as Exclude, but for strings only.
type Diff<T extends string, U extends string> = ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T]
type Omit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>
І приклад такого типу у використанні:
interface Test {
a: string;
b: number;
c: boolean;
}
// Omit a single property:
type OmitA = Omit<Test, "a">; // Equivalent to: {b: number, c: boolean}
// Or, to omit multiple properties:
type OmitAB = Omit<Test, "a"|"b">; // Equivalent to: {c: boolean}
Omit<{a?: string, b?: boolean}, "b">
призводить до того {a: string | undefined}
, що все ще приймає undefined
як значення, але втрачає необов’язковий модифікатор увімкнено a
. :(
Pick
, наскільки я бачу.
Omit
відрізняється від наведеного тут. На думку stdlib, саме type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
Зміна, хоча і незначна, викликала певні дискусії , тож знайте про різницю.
За допомогою typecript 2.8 ви можете використовувати новий вбудований Exclude
тип. У нотатках 2,8 релізу на насправді говорити про це в розділі «зумовленої умовні типів»:
Примітка. Тип Exclude - це належна реалізація запропонованого тут типу Diff. [...] Ми не включили тип Оміт, тому що він тривіально пишеться як
Pick<T, Exclude<keyof T, K>>
.
Застосувавши це до свого прикладу, тип XY можна визначити як:
type XY = Pick<XYZ, Exclude<keyof XYZ, "z">>
Я знайшов рішення із оголошенням деяких змінних та використанням оператора спред для виводу типу:
interface XYZ {
x: number;
y: number;
z: number;
}
declare var { z, ...xy }: XYZ;
type XY = typeof xy; // { x: number; y: number; }
Це працює, але я би радий побачити краще рішення.
typeof
є однією з найбільш недооцінених особливостей машинопису.
type Smth = XY & { z: string };
,?
Якщо ви віддаєте перевагу використовувати бібліотеку, використовуйте ts-basics .
import { Omit } from "ts-essentials";
type ComplexObject = {
simple: number;
nested: {
a: string;
array: [{ bar: number }];
};
};
type SimplifiedComplexObject = Omit<ComplexObject, "nested">;
// Result:
// {
// simple: number
// }
// if you want to Omit multiple properties just use union type:
type SimplifiedComplexObject = Omit<ComplexObject, "nested" | "simple">;
// Result:
// { } (empty type)
PS: Ви знайдете там багато інших корисних речей;)
Станом на Typescript 3.5, помічник пропуску буде включений: TypeScript 3.5 RC - тип опускання помічника
Ви можете використовувати його безпосередньо, і ви повинні видалити власне визначення помічника пропускати під час оновлення.
У Typescript 3.5+ :
interface TypographyProps {
variant: string
fontSize: number
}
type TypographyPropsMinusVariant = Omit<TypographyProps, "variant">
Мені так подобається:
interface XYZ {
x: number;
y: number;
z: number;
}
const a:XYZ = {x:1, y:2, z:3};
const { x, y, ...last } = a;
const { z, ...firstTwo} = a;
console.log(firstTwo, last);
Diff<T, U>
(із типамиT
таU
типи, доступними для клавішів) якT
підмножина перетину з 3-х типів: тип з ключем, як значення дляT
, введітьnever
дляU
і введітьnever
для всіх клавіш. Потім ви передаєте його через індексатор, щоб отримати правильні типи значень. Маю рацію?