Réponses:
Dans TypeScript 3.5, le Omit
type a été ajouté à la bibliothèque standard. Voir les exemples ci-dessous pour savoir comment l'utiliser.
Dans TypeScript 2.8, le Exclude
type a été ajouté à la bibliothèque standard, ce qui permet à un type d'omission d'être écrit simplement comme:
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
Vous ne pouvez pas utiliser le Exclude
type dans les versions inférieures à 2.8, mais vous pouvez créer un remplacement pour lui afin d'utiliser le même type de définition que ci-dessus. Cependant, ce remplacement ne fonctionnera que pour les types de chaîne, il n'est donc pas aussi puissant que 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>>
Et un exemple de ce type en cours d'utilisation:
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">
results in {a: string | undefined}
, qui accepte toujours undefined
comme valeur, mais perd le modificateur facultatif activé a
. :(
Pick
autant que je puisse voir.
Omit
diffère de celle donnée ici. Dans le stdlib, c'est type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
Le changement, bien que léger, a provoqué un débat , alors soyez conscient de la différence.
Avec typescript 2.8, vous pouvez utiliser le nouveau type intégré Exclude
. Les notes de version 2.8 le mentionnent en fait dans la section «Types conditionnels prédéfinis»:
Remarque: le type Exclude est une implémentation correcte du type Diff suggéré ici. [...] Nous n'avons pas inclus le type Omit car il s'écrit trivialement comme
Pick<T, Exclude<keyof T, K>>
.
En appliquant ceci à votre exemple, le type XY pourrait être défini comme:
type XY = Pick<XYZ, Exclude<keyof XYZ, "z">>
J'ai trouvé une solution en déclarant certaines variables et en utilisant l'opérateur spread pour déduire le type:
interface XYZ {
x: number;
y: number;
z: number;
}
declare var { z, ...xy }: XYZ;
type XY = typeof xy; // { x: number; y: number; }
Cela fonctionne, mais je serais heureux de voir une meilleure solution.
typeof
est l'une des caractéristiques les moins appréciées de la dactylographie.
type Smth = XY & { z: string };
?
Si vous préférez utiliser une bibliothèque, utilisez 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: Vous y trouverez plein d'autres trucs utiles;)
À partir de Typescript 3.5, l'assistant Omit sera inclus: TypeScript 3.5 RC - Le type d'aide Omit
Vous pouvez l'utiliser directement et vous devez supprimer votre propre définition de l'assistant Omettre lors de la mise à jour.
Dans Typescript 3.5+ :
interface TypographyProps {
variant: string
fontSize: number
}
type TypographyPropsMinusVariant = Omit<TypographyProps, "variant">
J'aime ça:
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>
(avecT
etU
comme types disponibles pour les clés) comme unT
sous-ensemble à clé d'une intersection de 3 types: tapez avec clé identique à une valeur pourT
, tapez avecnever
forU
et tapez avecnever
pour toutes les clés. Ensuite, vous le passez via l'indexeur pour obtenir les types de valeurs corrects. Ai-je raison?