简体   繁体   English

映射类型:根据同一个 object 的数组是否包含字符串字面量,使属性成为必需

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

Is it possible to make an object property dependent on whether an array of the same object contains a 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 
})

By using an identity function to create your structs (and a predicate to discriminate its type), you can accomplish this:通过使用标识 function 来创建结构(以及区分其类型的谓词),您可以完成此操作:

TS Playground 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.

相关问题 将已区分的并集(或对象类型数组)转换为以文字属性为键的映射类型 - Convert discriminated union (or array of object types) into a mapped type with a literal property as the key 从 TypeScript 中的数组创建字符串文字类型 - Make a String Literal Types from an Array in TypeScript TypeScript-使用数组文字初始化必需的属性时转换为对象 - TypeScript - Casting to Object When Initializing Required Property with an Array Literal 在 TypeScript 中使用字符串文字基于对象属性的动态返回类型 - Dynamic return type based on object property using string literal in TypeScript 将打字稿字符串文字类型转换为字符串数组 - Coverting typescript string literal types to an array of string 如何使用字符串文字类型使 function 重载? - How to make function overloading with string literal types? 从对象数组中获取字符串文字类型 - Get string literal types from Array of objects typescript 转换 Object.entries 将派生字符串数组减少为文字类型 - typescript converting Object.entries reduced derived string array to literal types TypeScript 映射类型以表示具有可选 Observables 的 object(使用字符串文字映射键) - TypeScript mapped type to represent an object with optional Observables (with string literal mapped keys) 是否可以通过 Typescript 中的映射类型将文字对象中的值(不是键)作为文字而不是其类型(例如字符串)获取? - Is it possible to get the value (not key) in a literal object as a literal, not its type (such as string) via mapped type in Typescript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM