简体   繁体   English

Typescript - 条件型/可选

[英]Typescript - Conditional Type / Optional

I have a component, It takes arguments such as:我有一个组件,它需要 arguments 例如:

interface Props {
  label: string;
  children?: React.ReactNode;
  withoutActions?: boolean;
  fieldKey?: KeyProperties;
  corporate: Corporate;
}

The withoutActions and fieldKey are used by a form. withoutActionsfieldKey由表单使用。 If the withoutActions prop is true , then there should not be a provided fieldKey .如果withoutActions 属性true ,则不应提供fieldKey

However, if my withoutActions is undefined , then i should enforce my fieldLabel to be of type **KeyProperties** which is a specific list of available values for it.但是,如果我的withoutActionsundefined ,那么我应该强制我的fieldLabel**KeyProperties**类型,这是可用值的特定列表。

If withoutActions is undefined, the other SHOULD NOT be defined at all If withoutActions is true, the other SHOULD be defined respecting the specific keyProperties type.如果 withoutActions 未定义,则根本不应该定义另一个 如果 withoutActions 为真,则应该根据特定的 keyProperties 类型定义另一个。

How can i implement that?我该如何实施?

I did not fully understand your requirement, but I would use a type alias instead of an interface.我没有完全理解您的要求,但我会使用类型别名而不是接口。 Eg something like this:例如这样的:

  type Props = {
    label: string,
    children?: React.ReactNode,
    withoutActions: true,
    corporate: Corporate
  } | {
    label: string,
    children?: React.ReactNode,
    withoutActions: undefined,
    fieldKey: KeyProperties,
    corporate: Corporate
  }

Similar to the other answer, but you can refactor it a bit to be cleaner.与其他答案类似,但您可以对其进行一些重构以使其更清洁。 You did not specify what the expected behavior is if withoutActions is false instead of true or undefined .如果withoutActionsfalse而不是trueundefined ,您没有指定预期的行为是什么。 Here, I assume the behavior for false and undefined are the same.在这里,我假设falseundefined的行为是相同的。 If false is not a valid type, you could just swap withoutActions?: false for withoutActions: undefined like the other answer.如果false不是有效类型,您可以像其他答案一样将withoutActions?: false withoutActions: undefined

type Props = {
  label: string;
  children?: React.ReactNode;
  corporate: Corporate;
} & (
  {
    withoutActions: true;
  } |
  {
    withoutActions?: false;
    fieldKey: KeyProperties;
  }
)

However, there is an important pitfall here that you should be aware of.但是,您应该注意一个重要的陷阱。 Because of TypeScript's structural typing, you only get excess property checking when you are directly assigning an object literal.由于 TypeScript 的结构类型,只有在直接分配 object 文字时才会进行过多的属性检查。 You do not get excess property checking when you assign an an object as an inferred type.将 object 分配为推断类型时,不会进行过多的属性检查。 TypeScript and React treat direct props declarations as if they are object literals, and will do excess property checking like you seem to desire. TypeScript 和 React 将直接 props 声明视为 object 文字,并且会像您希望的那样进行过多的属性检查。 However in some cases, if you assign objects to variables and let their type be inferred, TypeScript may not warn that there is an excess property present.但是在某些情况下,如果您将对象分配给变量并推断它们的类型,TypeScript 可能不会警告存在多余的属性。

Check out this demo based on your original example . 根据您的原始示例查看此演示 Example #1 and #2 will error because of excess property checking, but example #3 will not.示例 #1 和 #2 会因为过多的属性检查而出错,但示例 #3 不会。

const ExampleOne = () => {
  // Type error - excess property checking
  return <Component label={''} corporate={''} withoutActions fieldKey={''} />;
}

const ExampleTwo = () => {
  const props: Props = {
    label: '',
    corporate: '',
    withoutActions: true,
  // Type error - excess property checking
    fieldKey: '',
  }

  return <Component {...props} />;
}

const ExampleThree = () => {
  const props = {
    label: '',
    corporate: '',
    withoutActions: true,
    fieldKey: '',
  }

  // No type error - no excess property checking
  return <Component {...props} />;
}

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

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