如果存在另一个道具,则完全包含 Typescript 界面道具

Include Typescript interface props entirely if another prop exists

我有以下接口:

interface MyDialogProps extends DialogProps {
  title: string;
  subtitle?: string;
  action?: React.ReactNode;
  form?: boolean;
}

interface MyFormProps <Values extends object> {
  values: Values;
  onSubmit: (values: Values) => Promise <{}> ;
}

我需要在这两个接口之间有一个 union/intersection type 来表示当且仅当 form 时才需要 valuesonSubmit提供或 true.

您可以使用 conditional types 执行此操作。我们根据 form 是否定义为 true.

检查泛型和 return 不同类型的值
type FormPropsUnion<Values extends { form?: boolean }> =
    Values extends { form: true }
    ? MyFormProps<Values>
    : Partial<MyFormProps<Values>>

formtrue时,需要valuesonSumbit,当formfalseundefined时,这些字段是可选的。

请注意,typescript 正在检查 formtype,而不是 formvalue,因此,在任何想要 return 精炼类型的函数中使用适当的泛型非常重要。 FormPropsUnion<MyDialogProps> 的类型将具有可选属性,因为我们不知道 form 将始终为真。

但是如果我们正在处理 MyDialogProps 的特定实例,那时候我们可以使用泛型 P extends MyDialogProps 来根据 form 的值获得正确的类型。

declare function makeProps<P extends MyDialogProps>(props: P): FormPropsUnion<P>;

const one = makeProps({title: "", form: true}); // required fields 

const two = makeProps({title: ""}); // optional fields

Typescript Playground Link