簡體   English   中英

如何擴展類型參數以使其僅允許字符串文字類型但不允許“字符串”本身?

[英]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的任何內容。 如果Tstring ,則輸出將是string (如果string不是U的子類型)或never (如果stringU的子類型)。 字符串文字類型string的子類型,反之亦然,這給出了您正在尋找的行為。

Playground 代碼鏈接

暫無
暫無

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

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