簡體   English   中英

TypeScript:部分“部分”類型

[英]TypeScript: Partially "Partial" type

環境

TypeScript 的版本是 3.2.1,“tsconfig.json”如下所示。

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "esModuleInterop": true
  }
}

問題

我在 TypeScript 中尋找部分“部分”類型。

type Entity = {
  a: string,
  b: string,
  c?: string,
};

type Ham = MyType<Entity, 'b'>;
/**
 * expected to equal
 * {
 *   a: string,
 *   b?: string, // changed to be optional
 *   c?: string,
 * };
 */

PS Titian 和 t7yang

謝謝您的回復。 我檢查了你的類型,然后兩種類型都通過了編譯器的檢查!

const abc = { a: 'a', b: 'b', c: 'c' };
const ab = { a: 'a', b: 'b' };
const ac = { a: 'a', c: 'c' };
const a = { a: 'a' };

// by t7yang
let test1Abc: OptionalKey<Entity, 'b'> = abc;
let test1Ab: OptionalKey<Entity, 'b'> = ab;
let test1Ac: OptionalKey<Entity, 'b'> = ac;
let test1A: OptionalKey<Entity, 'b'> = a;

// by Titian Cernicova-Dragomir    
let test2Abc: PickPartial<Entity, 'b'> = abc;
let test2Ab: PickPartial<Entity, 'b'> = ab;
let test2Ac: PickPartial<Entity, 'b'> = ac;
let test2A: PickPartial<Entity, 'b'> = a;

您可以將PickPartial結合使用以僅選擇要作為可選項的屬性,同時使用Exclude保留其余屬性以獲取除傳入的鍵以使其成為可選項之外的鍵:

type Entity = {
   a: string,
   b: string,
   c?: string,
};

type PickPartial<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>> & Partial<Pick<T, K>> 
type Ham = PickPartial<Entity, 'b'>; // a, b? , c?
type Entity = {
  a: string,
  b: string,
  c?: string,
};

type OptionalKey<T, O extends keyof T> = Pick<T, Exclude<keyof T, O>> & Partial<{ [P in O]: T[P] }>;

const a: OptionalKey<Entity, 'b'> = {
  a: 'a',
}

const ab: OptionalKey<Entity, 'b'> = {
  a: 'a',
  b: 'b'
}

const ac: OptionalKey<Entity, 'b'> = {
  a: 'a',
  c: 'c'
}

我的想法是選擇所有想要制作可選項的屬性,然后與我們想要使屬性可選的類型合並。

你可以在打字稿操場上查看

真正簡單的解決方案:

type PickPartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
type PartialExcept<T, K extends keyof T> = Pick<T, K> & Partial<Omit<T, K>>;

Titian 的解決方案是在Typescript 3.5 之前編寫的,其中添加了 Omit helper

還要記住,您可以使用字符串聯合來選擇多個屬性以使其成為可選的:

type Full = {
  a: string;
  b: string;
  c: string;
}

// These are equivalent
type ARequired = PickPartial<Full, 'b' | 'c'>;
type ARequired = PartialExcept<Full, 'a'>;

接受答案的簡單版本(使用Intersection of a PartialPick )沒有任何中間類型來混淆事物:

type Entity = {
  a: number,
  b: number,
  c?: number,
}

type Ham = Partial<Entity> & Pick<Entity, Exclude<keyof Entity, 'b'>>;

const b: Ham[] = [{ a: 1 }, { a: 1, b: 1 }, { a: 1, c: 1 }, { a: 1, b: 1, c: 1 }]; // OK.
const c: Ham = {}; // Bad.

操場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM