簡體   English   中英

為什么 TypeScript 在嘗試從聯合類型中讀取 never 時不抱怨?

[英]Why TypeScript does not complain when trying to read from never in an union type?

我認為TypeScript在嘗試讀取可能是arraynever的屬性length時會抱怨,然后我需要使用類型謂詞縮小類型范圍。 不是這種情況。 為什么? 我怎么能改變類型所以 TypeScript 強制我檢查我不是在處理一個空的 object?

// strictNullChecks = true
type Empty = Record<string, never>;

type NonEmpty = {
  documents: Array<number>;
};

function isEmpty(x: Empty | NonEmpty): x is Empty {
  return !("documents" in x);
}

const count = (x: Empty | NonEmpty) => {
  // TypeScript does not complain about reading `length` property of `never`
  // if (isEmpty(x)) {
  //   return 0;
  // }
  return x.documents.length;
};

永遠不會從聯合類型中刪除(例如 0 + 5 = 5)。

type Test1 = never | string // string

從不覆蓋交集類型中的其他類型。 (例如 0 x 5 = 0)

type Test2 = never & string // never

文檔: https://www.typescriptlang.org/docs/handbook/2/narrowing.html#the-never-type

下面是一個逐步類型的銷毀示例:

type Empty = Record<string, never>;

type NonEmpty = {
  documents: Array<number>;
};

function isEmpty(x: Empty | NonEmpty): x is Empty {
  return !("documents" in x);
}

const count = (x: Empty | NonEmpty) => {

  type D0 = typeof x.documents
  type D1 =  (Empty | NonEmpty)[`documents`]
  type D2 = Empty[`documents`] | NonEmpty[`documents`]
  type D3 =  never | NonEmpty[`documents`]
  type D4 =  NonEmpty[`documents`]
  type D5 =  Array<number>

  return x.documents.length; // x.documents is number[], that's why no error here
};

以下是可能符合您需要的預期行為示例:

type EmptyExpected = Record<string, undefined>;

const countExpected = (x: EmptyExpected | NonEmpty) => {

  type D0 = typeof x.documents
  type D1 =  (EmptyExpected | NonEmpty)[`documents`]
  type D2 = EmptyExpected[`documents`] | NonEmpty[`documents`]
  type D3 =  undefined | NonEmpty[`documents`]
  type D4 =  undefined | number[]

  return x.documents.length; // x.documents is number[] | undefined, that's why it is an error here
};

TypeScript 游樂場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM