Mülkü türden hariç tut


199

Türden tek bir özelliği çıkarmak istiyorum. Bunu nasıl yapabilirim?

Örneğin bende var

interface XYZ {
  x: number;
  y: number;
  z: number;
}

Ve mülkiyeti zalmak için dışlamak istiyorum

type XY = { x: number, y: number };

Yanıtlar:


395

TypeScript sürümleri 3.5 veya üstü için

TypeScript 3.5'te, Omittür standart kitaplığa eklenmiştir. Nasıl kullanılacağını öğrenmek için aşağıdaki örneklere bakın.

TypeScript'in 3.5'in altındaki sürümleri için

TypeScript 2.8'de Excludetür, standart kitaplığa eklenmiştir ve bu, bir ihmal türünün basitçe şu şekilde yazılmasına olanak tanır:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>

TypeScript'in 2.8'in altındaki sürümleri için

ExcludeTürü 2.8'in altındaki sürümlerde kullanamazsınız , ancak yukarıdaki ile aynı türden tanımlamayı kullanmak için onun yerine bir yedek oluşturabilirsiniz. Bununla birlikte, bu değiştirme yalnızca dizge türleri için işe yarayacaktır, bu nedenle 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>>

Ve kullanımda olan bu türün bir örneği:

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}

Harika! Bu bildirmek Diff<T, U>ile ( Tve Ubir şekilde anahtarlar için uygun tipleri gibi) Tbir değeri olarak anahtar aynı tipte: -keyed 3 tip bir kavşak alt kümesi T, tip neveriçin Uolan ve tip neverbütün anahtarlar için. Ardından, doğru değer türlerini almak için onu dizinleyiciden geçirirsiniz. Haklı mıyım
Qwertiy

5
Evet! Ancak bunun bir dezavantajı var. Örneğin, hala bir değer olarak kabul eden, ancak isteğe bağlı değiştiriciyi kaybeden Omit<{a?: string, b?: boolean}, "b">sonuçlanır . :({a: string | undefined}undefineda
CRice

1
@Qwertiy Çalışıyor! Çok teşekkürler! Gönderiyi düzenledim. Ama farkın ne olduğunu merak ediyorum, çünkü Pickgörebildiğim kadarıyla tür tanımıyla tam anlamıyla aynı olan ne vardı .
CRice

3
TS 3.5 için, standart kitaplığın tanımının Omitburada verilenden farklı olduğuna dikkat edin. Stdlib'de, type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;değişiklik küçük olsa da bazı tartışmalara neden oldu , bu yüzden farkın farkında olun.
CRice

1
Hariç tutmaya çalıştığınız mülk yoksa, bunun şikayet olmadığını unutmayın. Örneğin Omit<Test, "doesNotExist">, hala geçerlidir. Bunu istemiyorsanız, kullanabileceğiniz StrictOmitgelen ts-temel yerine. Bu, mülkün yanlışlıkla yeniden adlandırılmasının ihmal kuralını ihlal etmediğinden emin olmak istiyorsanız kullanışlıdır.
CookieMonster

42

TypeScript 2.8 ile yeni yerleşik Excludetürü kullanabilirsiniz. 2.8 sürüm notları aslında bölümünde "Önceden tanımlanmış koşullu türleri" bu söz:

Not: Hariç tutma türü, burada önerilen Diff türünün uygun bir uygulamasıdır. [...] Olarak önemsiz şekilde yazıldığı için Atlama türünü dahil etmedik Pick<T, Exclude<keyof T, K>>.

Bunu örneğinize uygularsanız, XY türü şu şekilde tanımlanabilir:

type XY = Pick<XYZ, Exclude<keyof XYZ, "z">>

20

Bazı değişkenleri bildirmek ve türü çıkarmak için yayılma operatörünü kullanmakla çözüm buldum :

interface XYZ {
  x: number;
  y: number;
  z: number;
}

declare var { z, ...xy }: XYZ;

type XY = typeof xy; // { x: number; y: number; }

Çalışıyor, ancak daha iyi bir çözüm görmekten memnuniyet duyarım.


4
Bu harika bir 2.8 öncesi çözümdür. typeoftypcript'in daha az takdir edilen özelliklerinden biridir.
Jason Hoetger

1
Zekice, beğendim :)! (2.8 öncesi için)
maxime1992

Sonucunuza tür dizesi ile nasıl z ekleyebilirim
user602291

@ user602291, type Smth = XY & { z: string };?
Qwertiy

1
Bu, typcript'in eski sürümü için mükemmeldir. 2.3 için çalışmak için onaylanmış cevabı alamadım, ancak bu harika çalıştı.
k0pernikus

6

İçinde 3.5+ typescript :

interface TypographyProps {
    variant: string
    fontSize: number
}

type TypographyPropsMinusVariant = Omit<TypographyProps, "variant">

5

Kitaplık kullanmayı tercih ediyorsanız, ts-essentials kullanın .

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)

Not: Orada pek çok yararlı şey bulacaksınız;)



3

Çıkarmak

tek mülk

type T1 = Omit<XYZ, "z"> // { x: number; y: number; }

birden çok özellik

type T2 = Omit<XYZ, "y" | "z"> // { x: number; } 

şartlı özellikler

örneğin tüm dizi türleri:
type Keys_StringExcluded<T> = { [K in keyof T]: T[K] extends string ? never : K }[keyof T]

type XYZ = { x: number; y: string; z: number; }
type T3a = Pick<XYZ, Keys_StringExcluded<XYZ>> // { x: number; z: number; }
İle kısa versiyon TS 4.1 eşleştirilmiş tip asmaddesi:
type T3b = { [K in keyof XYZ as XYZ[K] extends string ? never : K]: XYZ[K] } 
// { x: number; z: number; }

stringdesene göre özellikler

örneğin, alıcıları hariç tut ('get' dizesi öneklerine sahip props)
type OmitGet<T> = { [K in keyof T as K extends `get${infer _}` ? never : K]: T[K] }

type XYZ2 = { getA: number; b: string; getC: boolean; }
type T4 = OmitGet<XYZ2> //  { b: string; }

Not: Yukarıdaki şablon değişmez türleri TS 4.1 ile desteklenir


Oyun alanı örneği


0

Bunu beğendim:

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);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.