[英]How do I extend a type argument so that it allows only string literal types but not 'string' itself?
我需要一種本質上是“除 {reservedKeywords} 之外的任何字符串”的類型。 然而,這顯然要么是不可能的,要么是棘手且笨拙的。
我可以滿足於必須指定要使用的字符串文字。 這是盡可能接近我想要的,使用Exclude<T,K>
:
type AnySet<set extends string> = set
let test1: Exclude<AnySet<"a" | "1">, "1">
test1 = "a" //passes correctly
test1 = "1" //fails correctly
let test2: Exclude<AnySet<string>, "1">
test2 = "a" //passes correctly
test2 = "1" //passes (counterintuitively :( )
有什么辦法可以禁止直接傳遞string
? 此外,有沒有辦法定義類型是字符串文字的任何集合,但不是專門的string
?
這就是我的意思:
type AnySet<set extends string> = set
let test1: Exclude<AnySet<"a" | "1">, "1">
test1 = "a" //passes correctly
test1 = "1" //fails correctly
let test2: Exclude<AnySet<string>, "1">
test2 = "a" //passes correctly
test2 = "1" //passes (counterintuitively)
type FiniteSet<set extends ???> = set
let test3: Exclude<FiniteSet<"a" | "1">, "1">
test3 = "a" //should work
test3 = "1" //should not work
let test4: FiniteSet<string> //should fail
let test5: FiniteSet<"a" | "b" | "c"> //should work
您可以使用遞歸約束(所謂的F-bounded quantification ),例如S extends Exclude<string, S>
:
type FiniteSet<S extends Exclude<string, S>> = S
let test3: Exclude<FiniteSet<"a" | "1">, "1">
test3 = "a" // okay
test3 = "1" // error
let test4: FiniteSet<string> // error
let test5: FiniteSet<"a" | "b" | "c"> // okay
這是因為Exclude<T, U>
實用程序類型過濾T
中的聯合以刪除可分配給U
的任何內容。 如果T
是string
,則輸出將是string
(如果string
不是U
的子類型)或never
(如果string
是U
的子類型)。 字符串文字類型是string
的子類型,反之亦然,這給出了您正在尋找的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.