网站搜索

我可以在 TypeScript 中检查哪些属性


在使用 TypeScript 时,我意识到我并不完全理解属性检查是如何工作的。在下面的示例中,我不明白为什么检查 .bold 可行,但检查 .type 却不可行。

type CustomText = {
    bold: boolean;
};

type TitleElement = { type: 'title'; children: string };

type Element = TitleElement | CustomText;

const el: Element = {
  bold: true,
}

if (!el.bold) {
  console.log("does not have bold")
}

if (!el.type) { // <- compiler error
  console.log("does not have type")
}

答案#1

看起来,TypeScript 已经知道你输入的元素是什么类型(CustomText),因为它在你的代码中是静态分配的。如果它是动态的,TS 会对两者都报错。

例如:

const getElem = () => {
  if(Math.floor((Math.random() * 10) + 1)%2)
   {
      const x : TitleElement = { name: 'title', children: 'x' };
      return x;
   } 
  else{
      const x : CustomText = { bold: false };
      return x;
 
  }
}

type CustomText = {
    bold: boolean;
};

type TitleElement = { name: 'title'; children: string };

type Element2 = TitleElement | CustomText;

let el: Element2 = getElem();

if (!el.bold) {

  console.log("does not have bold")
}

if (!el.name) { // <- compiler error
  console.log("does not have type")
}

操场

联合的目的在于它允许来自所有联合参与者的属性。你可以轻松访问存在于 两者 CustomText 和 TitleElement 中的任何属性。TS 应该会报错,并且确实会报错。如果你像下面这样做,TS 会在两个 if 条件中都报错。

type CustomText = {
    bold: boolean;
    both : string;
};

type TitleElement = { name: 'title'; children: string, both : string; };

type Element2 = TitleElement | CustomText;

const el: Element2 = {
  bold: true,children: 'sing' 
}

if (!el.bold) {
  console.log("does not have bold")
}

if (!el.name) { // <- compiler error
  console.log("does not have type")
}

if (!el.both) { // <- compiler error
  console.log("does not have type")
}

这是因为现在 TS 再次不确定 Element2 的 type,它不能允许你访问在两者中都不存在的属性。

操场