如何根据另一种类型正确推断类型?

时间:2021-04-15 06:36:20

标签: typescript typescript-typings

tab{leftText: string, rightText?: string}时,我想将props.group对象的类型推断为true类型,当{title: string}props.group时推断为false类型type ButtonTab = | { leftText: string; rightText?: string; } | { title: string }; interface ButtonTabsProps { tabsList: ButtonTab[]; group?: boolean; } function ButtonTabs(props: Readonly<ButtonTabsProps>) { return props.tabsList.map((tab: ButtonTab) => { if(props.group) { return `${tab.leftText} ${tab.rightText}` } return `${tab.title}` }) }

x = [['I', 'ma', 'a'], ['s', 'p', 'e', 'a', 'k', 'ma', 'a'], ['G', 'o', 'a', 't', 'ma', 'a'], ['L', 'a', 't', 'i', 'n', 'ma', 'a']]

sentence = " ".join(["".join(y) for y in x])
print(sentence)

现在,TSC 抛出一个错误:

<块引用>

“ButtonTab”类型上不存在属性“leftText”。 属性 'leftText' 不存在于类型 '{ title: string; }'。

代码:TypeScript Playground

2 个答案:

答案 0 :(得分:2)

在您的代码中,props.group 属性与 ButtonTab 类型无关。

props.group 应该搬出去。

type ButtonTab<G extends boolean = true> = G extends true
  ? {
      leftText: string;
      rightText?: string;
    }
  : {title: string};

type ButtonTabsProps =
  | {
      tabsList: ButtonTab<true>[];
      group: true;
    }
  | {
      tabsList: ButtonTab<false>[];
      group: false;
    };

function ButtonTabs(props: ButtonTabsProps) {
  if (props.group) {
    return props.tabsList.map(tab => {
      return `${tab.leftText} ${tab.rightText}`;
    });
  }

  return props.tabsList.map(tab => {
    return `${tab.title}`;
  });
}

TS Playground

答案 1 :(得分:0)

interface ButtonTabText {
  leftText: string
  rightText?: string
}
interface ButtonTabTitle {
  title: string
}

interface ButtonTabsText {
  group: true
  tabsList: ButtonTabText[]
}
interface ButtonTabsTitle {
  group: false
  tabsList: ButtonTabTitle[]
}

type Props = ButtonTabsTitle | ButtonTabsText

const renderTabsText = (tabsList: ButtonTabText[]): string[] =>
  tabsList.map((tab) => `${tab.leftText} ${tab.rightText}`)

const renderTabsTitle = (tabsList: ButtonTabTitle[]): string[] =>
  tabsList.map((tab) => tab.title)

function ButtonTabs(props: Readonly<Props>) {
  return props.group
    ? renderTabsText(props.tabsList)
    : renderTabsTitle(props.tabsList)
}