簡體   English   中英

映射類型:根據同一個 object 的數組是否包含字符串字面量,使屬性成為必需

[英]Mapped types: Make property required based on whether array of same object contains string literal

是否可以根據相同 object 的數組是否包含字符串文字來制作 object 屬性?

type Operator = "A" |  "B"
type SomeStruct = {
    operators: Operator[];
    someProp: string; // this should be required if operators include "A", optional if not
}

// desired result
const structWithA: SomeStruct = {
  operators: ["A", "B"],
  someProp: "" // correct, since operators contains "A", someProp is required
};

const structWithB: SomeStruct = {
  operators: ["B"],
  // currently errors, but desired outcome is that it should not error, since operators does not contain "A"
};

declare const structs: SomeStruct[];

structs.map(struct => {
  if(struct.operators.includes("A")) {
    // someProp is safely accessible
  }

  // since .includes has a narrow type signature, maybe another way to safely access someProp is needed 
})

通過使用標識 function 來創建結構(以及區分其類型的謂詞),您可以完成此操作:

TS游樂場

type A = 'A';
type B = 'B';
type Operator = A | B;

type SomeStruct<T extends readonly Operator[]> = { operators: T; } & (
  T extends readonly A[] ?
    Record<'someProp', string>
    : unknown
);

function craeteStruct <O extends readonly Operator[], T extends SomeStruct<O>>(struct: T): T {
  return struct;
}

const structWithA = craeteStruct({
  operators: ["A", "B"],
  someProp: "",
});

const structWithB = craeteStruct({
  operators: ["B"],
});

declare const structs: (SomeStruct<Operator[]>)[];

function includesA (struct: SomeStruct<Operator[]>): struct is SomeStruct<A[]> {
  return struct.operators.includes('A');
}

structs.map(struct => {
  if(includesA(struct)) {
    struct.someProp; // string
  }
});

暫無
暫無

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

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