[英]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 一樣被索引。這包括像string
和number
這樣的原語,當你索引到它們時它們會被對象包裹起來(因此支持像"hello".toUpperCase()
和(123).toFixed(2)
). 在這個意義上,只有null
和undefined
不是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.