React - Typescript条件类型赋值

v7pvogib  于 2022-12-24  发布在  TypeScript
关注(0)|答案(2)|浏览(174)

我必须创建一个可以来自两种不同类型的组件。
一个月一个月一个月一个月一个月
据我所知,我可以将组件类型定义为
function Component<T extends A | B>(props T){ ... Stuff }
我可以称之为

const MyComponent : A = <Component a={"test"}/>
const MyComponent : B = <Component b={1231241}/>

我的问题是:当编码Component时,我如何导航 prop ,我需要做:

function Component<T extends A | B>(props T){ 
  let data; 
  if(props typeof A){
    data = props.a 
  }

  if(props typeof A){
    data = props.b 
  }

  console.log(data)
}

我不能使用typeof,因为它是用于原语的,但是instanceOf似乎只用于类。有什么线索吗?我做错了什么?

vh0rcniy

vh0rcniy1#

没有真实的干净的解决方案,因为类型在生成的JavaScript中不存在。我建议您在两种类型中添加一个共享字段,如type,这有助于TypeScript确定哪些属性可用:

type A = { a: string, type: "A" }
type B = { b: string, type: "B" }

function Component<T extends A | B>(props: T) {
  switch (props.type) { // or: if (props.type === "A") ...
    case 'A':
      // access props.a, TypeScript will infer it's there
      break;
    case 'B':
      // access props.b, TypeScript will infer it's there
      break;
  }
}

这种方法的优点是可以很好地扩展更多、更复杂的类型。
编辑:通常,类型检查可以通过用户定义的类型保护来完成:

const isTypeA = (toCheck: A | B): toCheck is A => 'a' in toCheck;

function Component<T extends A | B>(props: T) {
  if (isTypeA(props)) {
    // access props.a, TypeScript will infer it's there
  }
}

但是在大多数情况下我还是坚持使用第一种变体,它不太容易出错(类型保护方法可能出错),并且提供了前面提到的优点。

ffx8fchx

ffx8fchx2#

你可以试试这样的方法:

type A = { a: string } 
type B = { b: number }

function Component<T extends A | B>(props: T){ 
  let data; 
  
  if ('a' in props){
    data = props.a 
  } else if ('b' in props){
    data = props.b 
  }
  console.log(data)
}

TypeScript会根据if语句中的检查自动检测 prop 类型。

相关问题