ฉันต้องการยกเว้นคุณสมบัติเดียวจากประเภท ฉันจะทำสิ่งนั้นได้อย่างไร
เช่นฉันมี
interface XYZ {
x: number;
y: number;
z: number;
}
และฉันต้องการยกเว้นคุณสมบัติz
เพื่อรับ
type XY = { x: number, y: number };
ฉันต้องการยกเว้นคุณสมบัติเดียวจากประเภท ฉันจะทำสิ่งนั้นได้อย่างไร
เช่นฉันมี
interface XYZ {
x: number;
y: number;
z: number;
}
และฉันต้องการยกเว้นคุณสมบัติz
เพื่อรับ
type XY = { x: number, y: number };
คำตอบ:
ใน 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>>;
การเปลี่ยนแปลงในขณะที่เล็กน้อยทำให้เกิดการถกเถียงกันบ้างดังนั้นจงระวังความแตกต่าง
ด้วย typescript 2.8 คุณสามารถใช้Exclude
ชนิดบิวด์อินใหม่ได้ บันทึก 2.8 ปล่อยจริงกล่าวถึงนี้ในส่วน "ที่กำหนดไว้ล่วงหน้าประเภทเงื่อนไข":
หมายเหตุ: ประเภทการแยกเป็นการใช้งานประเภท Diff ที่แนะนำที่นี่ [... ] เราไม่ได้รวม Omit type เพราะมันเขียนเป็นเรื่อง
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
เป็นหนึ่งในคุณสมบัติที่ด้อยค่ามากขึ้นของ typescript
type Smth = XY & { z: string };
?
หากคุณต้องการใช้ห้องสมุดใช้TS-ข้อมูลสำคัญ
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: คุณจะพบสิ่งที่มีประโยชน์อื่น ๆ อีกมากมายที่นั่น;)
ตั้งแต่ Typecript 3.5 ผู้ช่วยOmitจะรวมอยู่ด้วย: TypeScript 3.5 RC - ประเภท Omit Helper
คุณสามารถใช้งานได้โดยตรงและคุณควรลบคำจำกัดความของตัวช่วย 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
เซต -keyed ตัดของ 3 ประเภทคือ: ประเภทที่มีคีย์เดียวกับค่าสำหรับT
ชนิดที่มีnever
สำหรับU
และประเภทที่มีnever
กุญแจทั้งหมด จากนั้นคุณส่งผ่านตัวสร้างดัชนีเพื่อรับชนิดค่าที่ถูกต้อง ฉันถูกไหม?