TS中是否可以轉換這種型別
type input = {
a: 1;
b: 2;
c: 3;
};
成這種型別
type output = { a: 1 } | { b: 2 } | { c: 3 };
?
uj5u.com熱心網友回復:
你可以這樣做:
type input = {
a: 1;
b: 2;
c: 3;
};
type output = { a: 1 } | { b: 2 } | { c: 3 };
let i : input = {
a: 1,
b: 2,
c: 3
};
let o : output;
let {a, b, c} = i;
o = {a} || {b} || {c};
uj5u.com熱心網友回復:
不確定這是否可以擴展到更復雜的input型別,嵌套的東西可能會變得很奇怪
type input = {
a: 1;
b: 2;
c: 3;
};
// given key K, construct {[K]: T[K]}
type m2<T, K extends keyof T> = {[k in K]: T[k]}
// for each key K in T, construct {[K]: T[K]}, and union the results
type m1<T, K extends keyof T> = K extends any ? m2<T, K> : never;
type map<T> = m1<T, keyof T>;
type result = map<input>
declare const result : result;
if ("a" in result) {
result.a // type 1
}
else if ("b" in result) {
result.b; // type 2
}
else {
result.c // type 3
}
uj5u.com熱心網友回復:
老實說,我不知道如何從頭開始實作它。但這里有一個庫可以做到這一點以及更多(ts-toolbelt):
import { Object } from 'ts-toolbelt';
type Input = {
a: 1;
b: 2;
c: 3;
};
type Output = Object.Either<Input, keyof Input>;
uj5u.com熱心網友回復:
您想要一個轉換Input為Output;的型別函式 讓我們稱之為“ Split<T>”,因為想要一個更好的名字。這是一種方法:
type Split<T extends object> =
{ [K in keyof T]-?: Pick<T, K> }[keyof T];
在內部,我們使用實用Pick<T, K>程式型別來表示與 相同的型別,T但僅使用來自K. 所以Pick<Input, "a">是{a: 1}:
type Test = Pick<Input, "a">
// type Test = { a: 1; }
外部是分布式物件型別(如microsoft/TypeScript#47109中所創造的),當您在一組鍵上創建映射型別,然后立即使用同一組鍵對其進行索引時,您會得到這種型別。我
分布式物件型別讓您可以為某些類似鍵的型別使用型別函式F<K>,并為某些鍵集中的每個聯合成員K生成聯合。在上述情況下,是一組鍵。所以上面將計算每個in的并集,這就是你想要的:F<K>Kkeyof TPick<T, K>Kkeyof T
type Input = {
a: 1;
b: 2;
c: 3;
};
type Output = Split<Input>;
// type Output = Pick<Input, "a"> | Pick<Input, "b"> | Pick<Input, "c">
如果您不喜歡Pick在 IntelliSense 輸出中看到,您可以行內into的定義Pick<T, K>Split<T>:
type Split<T extends object> =
{ [K in keyof T]-?: { [P in K]: T[P] } }[keyof T];
type Output = Split<Input>;
// type Output = { a: 1; } | { b: 2; } | { c: 3; }
Playground 代碼鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/494990.html
標籤:javascript 反应 打字稿
