早上好,
我正在努力實作以下目標,
創建一個型別,該型別將從以下物件中獲取鍵
const obj = {
setName: () => void;
setAge: () => void;
}
并使用映射型別生成 Tuple 型別
[ “setName”, “setAge” ]
我在這里可能完全錯了,但是對于映射型別,我認為這會起作用
type MyType<T> = {
[P in keyof T]: T[P]
}
但是如果 T 是我上面展示的物件的型別,我最終會得到以下型別
type MappedType = {
setName: () => void;
setAge: () => void;
}
但我想要的是
type MappedType = [setName, setAge]
任何幫助是極大的贊賞。
uj5u.com熱心網友回復:
你需要的是UnionToTuple<U>:
// T ====> [...T, E]
type Push<T, E> = T extends any[] ? [...T, E] : [];
// union to intersection of functions
// UnionToIoFn<'a' | 'b'>
// ====> ((x: 'a') => void) & ((x: 'b') => void)
// ====> that equal to { (x: 'a'): void; (x: 'b'): void }
type UnionToIoFn<U> =
(U extends any ? (k: (x: U) => void) => void : never) extends
((k: infer I) => void) ? I : never
// UnionPop<((x: 'a') => void) & ((x: 'b') => void)> ===> 'b'
// UnionPop<{ (x: 'a'): void; (x: 'b'): void }> ===> 'b'
type UnionPop<F> =
F extends ({ (x: infer X): void; })
? X
: never;
type UnionToTupleIter<U, Res> =
[U] extends [never]
? Res
: UnionToTupleIter<
Exclude<U, UnionPop<UnionToIoFn<U>>> ,
Push<Res, UnionPop<UnionToIoFn<U>>>
>
type UnionToTuple<U> = UnionToTupleIter<U, []>;
// test
const obj = {
setName: () => {},
setAge: () => {},
}
// You wanted
// type YouWanted = ["setAge", "setName"]
type YouWanted = UnionToTuple<keyof typeof obj>;
點擊這里在 ts playground 中嘗試代碼
uj5u.com熱心網友回復:
您真的需要 Tuple 型別還是 Array 型別可以?如果您只是需要('setName', 'setAge')[],您可以輕松撰寫(keyof typeof obj)[]。我認為沒有必要將其變成元組型別(這絕對是可能的),因為我不會依賴物件屬性的順序,并且元組通常會推斷出其中事物的修復順序。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/471277.html
