Ответы:
В 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в качестве значения, но теряет необязательный модификатор on a. :(
Pickнасколько я могу видеть.
Omitотличается от приведенного здесь. В stdlib это type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;изменение, хотя и незначительное, вызвало некоторые споры , так что имейте в виду разницу.
С машинописным текстом 2.8 вы можете использовать новый встроенный Excludeтип. В заметках 2,8 релиза на самом деле говорить об этом в разделе «предопределенной условные типов»:
Примечание. Тип Exclude является правильной реализацией предложенного здесь типа Diff. [...] Мы не включили тип Omit, потому что он тривиально записан как
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-essentials .
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, будет включен помощник Omit: TypeScript 3.5 RC - Тип помощника Omit
Вы можете использовать его напрямую, и вы должны удалить свое собственное определение помощника Omit при обновлении.
В 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для всех ключей. Затем вы передаете его через индексатор, чтобы получить правильные типы значений. Я прав?