![](/img/trans.png)
[英]Unable to set a dynamic value to predefined object in typescript
[英]TypeScript: Type to contain any value EXCEPT values from a predefined set
是否可以使用包含任何值的類型但是來自預定義集合的值?
type Fruit = 'Apple' | 'Banana' | 'Orange'
type NotFruit = ???
const a: NotFruit = 'Carrot'; // Compiler OK.
const b: NotFruit = 'Apple'; // Compiler ERROR.
即是否存在NotFruit
的定義, NotFruit
編譯器根據我的代碼中的注釋進行響應?
我會回答說這絕對不可能使用Typescript。 語言中的集合沒有否定運算符。
您可以創建一個instanceOf typeguard。
https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards
type Fruit = "Apple" | "Orange";
function isFruit(fruit: string): fruit is Fruit {
return !(['Apple', 'Orange'].includes(fruit));
}
TypeScript目前不支持否定類型作為具體類型,但也許它們有一天會被支持。
目前,表達否定類型的唯一方法是間接地 ,通過驗證條件是否滿足的泛型類型。
就像是:
type DefinitelyNot<T, C> = [T] extends [C]
? Invalid<[C, "is prohibited because it might be", T]>
: [C] extends [T]
? Invalid<[C, "is prohibited because it is assignable to", T]>
: C;
類型DefinitelyNot<T, C>
采用類型T
否定,並采用候選類型C
如果我們可以確定C
與T
不兼容,那么我們返回C
本身。 否則,我們返回C
將不匹配的內容,特別是導致錯誤的Invalid
類型。 好了,我們會這么做,如果無效類型提供了支持 ,這是他們目前還沒有。 所以我們也需要一個解決方法:
type Invalid<Msg> = Msg & Error;
它會產生一些相當丑陋的錯誤消息,但至少開發人員可能有機會弄清楚錯誤出現的原因。 然后我們可以創建一個帶有類型T
函數,並生成一個只接受與T
不兼容的參數的新函數:
const makeNot = <T>() => <C>(val: C & DefinitelyNot<T, C>): C => val;
我們來試試吧:
type Fruit = "Apple" | "Banana" | "Orange";
const asNotFruit = makeNot<Fruit>();
const a = asNotFruit("Carrot"); // okay
const b = asNotFruit("Apple"); // error
// ┌--------------> ~~~~~~~
// ["Apple", "is prohibited because it is assignable to", Fruit]
function someRandomFunction(x: string, y: number) {
const c = asNotFruit(x); // error
// ┌---------------> ~
// [string, "is prohibited because it might be", Fruit]
const d = asNotFruit(y); // okay (a number cannot be Fruit)
}
正如你所看到的, "Carrot"
和number
被接受了,因為那些絕對不是Fruit
。 "Apple"
被拒絕了,因為它肯定是 Fruit
,並且string
被拒絕,因為它可能是 Fruit
。
不確定你是否想要使用這種解決方案,但我想我還是要包含它。 希望有所幫助。 祝好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.