简体   繁体   English

TypeScript:如何缩小/编写复杂条件类型的保护?

[英]TypeScript: How do I narrow / write a guard for a complex conditional type?

Given the following MultiselectValue conditional type, how do I make it resolve to either LabeledValue<T> or Array<LabeledValue<T>> based on the value of multiple or via a guard inside Comp ?给定以下MultiselectValue条件类型,如何根据multiple的值或通过Comp中的守卫将其解析为LabeledValue<T>Array<LabeledValue<T>>

export interface LabeledValue<T = unknown> {
  label: string;
  value: T;
}

export type MultiselectValue<T, Multiple> = Multiple extends (undefined | false)
  ? LabeledValue<T>
  : Array<LabeledValue<T>>;

export type MultiselectProps<T, Multiple extends boolean | undefined> = {
  multiple: Multiple;
  value: MultiselectValue<T, Multiple>;
}

Comp({
  multiple: true,
  value: [{ // tsc complains if not an array (as expected) because 'multiple' is 'true'
    label: 'Option 1',
    value: 5
  }]
});

function Comp<T, Multiple extends boolean | undefined = undefined>(props: MultiselectProps<T, Multiple>) {
  const { multiple, value } = props;

  if (multiple) {
    // value is an arrray here
  } else {
    // value is a string here
  }
}

TS Playground link TS Playground 链接

The easiest way is to actually change the definition of MultiselectProps :最简单的方法是实际更改MultiselectProps的定义:

type MultiselectProps<T, Multiple extends boolean | undefined> = Multiple extends (undefined | false) ? {
  multiple: Multiple;
  value: LabeledValue<T>;
} : {
  multiple: Multiple;
  value: Array<LabeledValue<T>>;
};

Now, in the function body, props is a discriminated union (unresolved type), which means you can narrow it like you already have done.现在,在 function 主体中, props是一个可区分的联合(未解析类型),这意味着您可以像以前那样缩小它。

Playground操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM