[英]Mapped types + function parameters enigma
下面的當前示例仍然無法完全滿足我的要求(示例:操縱redux reducers的函數)。 此函數輸出所需的類型,但允許不期望的輸入( c: 'hello'
)。 在這里,似乎確實需要用到彎彎曲曲的技巧來按順序進行編譯。
type Reducer<State> = (s: State, p: any) => State
const reducerMap = <State>(s: State) => <
ScopedReducers extends { [k in keyof State]: Reducer<State[k]> }
>(
input: ScopedReducers
): { [k in keyof ScopedReducers]: Reducer<State> } => {
return undefined as any
}
const state = { a: 1, b: "2" }
const mapped = reducerMap(state)({
a: state => state + 1,
b: state => state + "_",
c: "hello",
})
ScopedReducers
是一個與State
有某種關系的對象(每個鍵都是Reducer<State[k]>
),但有自己的自由部分(reduceor有效負載)。 ScopedReducers
僅應包含State
也具有的鍵。 ScopedReducers
分配給它的約束,則其函數輸入將正確驗證。 如果我在State
放置一個不存在的額外密鑰,則編譯器將按預期方式出錯。
payload
部分。 此類型將擦除為any
。 ScopedReducers
擴展了它的約束,那么它的類型不會被擦除,並且可以在組成動態映射函數返回時使用。
extends
,因此function參數現在接受無關的鍵(例如: e : 2
)。 關系驗證仍適用於適用的密鑰。 而且“真正的野獸”是此個人項目上此文件中文件的最后一個功能,它也存在一個“ keyof”問題,我認為可能無法解決...
不必過多擔心代碼中發生的事情,也不必擔心問題的ScopedReducers
,我認為您正在嘗試使ScopedReducers
成為所謂的“ 精確類型” ,該類型 精確地包含指定的屬性:不少於不多。 不幸的是,這種類型在語言中尚不存在。 幸運的是,由於TypeScript 2.8中引入了條件類型 ,因此現在有一種方法可以要求類型參數的行為類似於精確類型,這是您所需要的。
讓我們介紹一下Exactify<T, X>
:
type Exactify<T, X extends T> = T & {
[K in keyof X]: K extends keyof T ? X[K] : never
}
並想象一下Exactify<T, X>
對於某個T
Exactify<T, X>
當泛型類型參數X
約束為Exactify<T, X>
時,會發生什么:
declare function exactlyFoo<X extends Exactify<Foo, X>>(x: X): void;
X extends Exactify<Foo, X>
是什么意思? 如果X
僅具有與Foo
相同的鍵,則X extends Exactify<Foo, X>
意味着僅X extends T & X
,也就是X extends T
但是,如果X
甚至在Foo
不存在一個鍵(例如extraKey
),則X extends Exactify<Foo, X>
變為X extends T & X & { extraKey: never }
,除非屬性extraKey
類型為never
否則這是不可能的。 實際上,這意味着您無法添加額外的密鑰。
如果我將Exactify<>
應用於您的代碼,它將變為:
const reducerMap = <State>(s: State) => <
ScopedReducers extends Exactify<
{ [k in keyof State]: Reducer<State[k]> }, ScopedReducers>>(
input: ScopedReducers
): { [k in keyof ScopedReducers]: Reducer<State> } => {
return undefined as any
}
並使用它:
const state = { a: 1, b: "2" }
const mapped = reducerMap(state)({
a: state => state + 1,
b: state => state + "_",
c: "hello", // error!
})
您在屬性c
收到所需的錯誤。 希望能有所幫助。 祝好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.