簡體   English   中英

typescript 類型條件擴展 object

[英]typescript type conditionals extends object

我想要條件類型,即 object。

type Id = {
    id: number
    obj: {
        x: 5
    }
}

type ObjString<T> = {
    [P in keyof T]:
        T[P] extends Object ? string : T[P]
}


const f: ObjString<Id> = {
    id: 4,
    obj: "xxxx"
}

在這里, obj屬性已正確映射到f object 中的字符串,但對於id屬性,我將收到此錯誤消息:

error TS2322: Type 'number' is not assignable to type 'string'.

這意味着T[P] extends Object對於number被評估為 true 。 我應該如何構造條件,以便 number 的計算結果為 false,而 object 的計算結果為 true?

Object類型並不真正對應於 TypeScript 中的非原始類型; 相反,它是一個值的類型,可以像 object 一樣被索引。這包括像stringnumber這樣的原語,當你索引到它們時它們會被對象包裹起來(因此支持像"hello".toUpperCase()(123).toFixed(2) ). 在這個意義上,只有nullundefined不是Object Object中的 Object 很少是您想要的。

如果您試圖在 TypeScript 中查找表示“非原始”的類型,則可以改用object類型(以小寫字母o而不是大寫字母O開頭):

type ObjString<T> = {
  [P in keyof T]:
  T[P] extends object ? string : T[P]
}

type Z = ObjString<Id>;
/* type Z = {
    id: number;
    obj: string;
} */

const f: ObjString<Id> = {
  id: 4,
  obj: "xxxx"
}

然后一切都按照你想要的方式進行。

請記住,盡管 arrays 和函數也是object s,因此您可能會遇到一些不良行為,具體取決於您想在那里看到的內容:

type Hmm = ObjString<{ foo(): string, bar: number[] }>;
// type Hmm = { foo: string; bar: string; }

游樂場代碼鏈接

這是因為Object類型太籠統了。 javascript 中的每個原始值都擴展Object ,因為即使是數字和字符串也有自己的方法。 考慮這個例子:

type Check1 = string extends Object ? true : false // true
type Check2 = number extends Object ? true : false // true

我認為最好從其他方面來解決問題。 您可以檢查類型是否為原始類型:

type Id = {
  id: number
  obj: {
    x: 5
  }
}

type Primitives = string | number | boolean | bigint | symbol;

type ObjString<T> = {
  [P in keyof T]:
  T[P] extends Primitives ? T[P] : string
}

const f: ObjString<Id> = {
  id: 4,
  obj: "xxxx"
}

操場

暫無
暫無

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

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