[英]Overriding the constraint type of the generic type in typescript
我創建了一個名為DataType
的通用類型助手,它接受一個參數 T,該參數 T 被限制為keyof MyObject
類型。 如果鍵存在於MyObject
中, DataType
將返回MyObject
的屬性類型; 否則,它將返回 T 本身。
interface MyObject {
foo: string;
bar: boolean;
}
export type DataType<T extends keyof MyObject> = T extends keyof MyObject
? MyObject[T]
: T;
現在,如果我傳遞MyObject
的任何鍵,它將返回相應的類型:
type StrType=DataType<'foo'>; // data type is string
但是,如果我將字符串以外的數據類型傳遞給此幫助程序,我將得到Type 'type' does not satisfy the constraint '"foo"'
:
type numType=DataType<number>;
如何不約束類型但仍然有MyObject
鍵的 IntelliSense 提示?
你真的不想約束T
; 它可以是任何東西,甚至是unknown
類型。 這可以通過將其保留為type DataType<T> =...
而不限制T
來實現。
interface MyObject {
foo: string;
bar: boolean;
}
type DataType<T> =
T extends keyof MyObject ? MyObject[T] : T;
type StrType = DataType<'foo'>; // string
type NumType = DataType<number>; // number
但如果你這樣做,你將失去提示keyof MyObject
的字符串文字類型成員的 IntelliSense 提示:
// type BooType = DataType<'⃒'>
// ----------------------> ^^ <---
// IntelliSense prompts here with NOTHING 😢
因此,您正在尋找的是一種等效於unknown
的類型,但具有keyof MyObject
的一些“內存”,IntelliSense 可以使用它。
您可能會想到使用聯合類型keyof MyObject | unknown
keyof MyObject | unknown
,但不幸的是, unknown
熱切地吸收聯合中的其他類型。 所以keyof MyObject | unknown
在 IntelliSense 有機會做任何事情之前, keyof MyObject | unknown
變為unknown
。
幸運的是,還有另一種類型在本質上類似於unknown
:union {} | null | undefined
{} | null | undefined
{} | null | undefined
。 所謂的空 object 類型{}
實際上接受任何非空類型,甚至像string
這樣的基元(這是因為string
有明顯的成員,如"length"
和"toUpperCase"
,所以string
是{length: number, toUpperCase(): string}
,它是{}
的子類型)。 唯一不可分配給{}
的值是null
和undefined
。 所以聯合{} | null | undefined
{} | null | undefined
{} | null | undefined
本質上與unknown
相同。 有一些細微差別,但您甚至可以將unknown
分配給{} | null | undefined
{} | null | undefined
{} | null | undefined
。
一個“小”區別是{} | null | undefined
{} | null | undefined
{} | null | undefined
不會急切地吸收聯合中的字符串文字。 所以keyof MyObject | {} | null | undefined
的聯合鍵keyof MyObject | {} | null | undefined
keyof MyObject | {} | null | undefined
保持不變,因此keyof MyObject
仍然可用於 IntelliSense 采取行動:
type DataType<T extends (keyof MyObject | {} | null | undefined)> =
T extends keyof MyObject ? MyObject[T] : T;
type StrType = DataType<'foo'>; // string
type NumType = DataType<number>; // number
// type BooType = DataType<'⃒'>
// ----------------------> ^^ <---
// IntelliSense prompts here with
// 🔧 bar
// 🔧 foo
type BooType = DataType<'bar'> // boolean
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.