【发布时间】:2018-03-21 01:09:06
【问题描述】:
我正在使用这些接口
/**
* Interface for entities
*/
export interface Entity extends Object {
readonly id: EntityId;
}
/**
* Interface for collection-based state
*/
export interface Collection<T extends Entity> extends Object {
readonly entities: { [key: string]: T };
readonly ids: EntityId[];
}
我正在编写一个辅助函数,它给定路径,增加集合中实体的相应值。
例子:
Collection.increment(myCollection, 'some-id', ['stats', 'total']);
这些是我目前的类型
export function increment<
C extends Collection<any>,
E = C extends Collection<infer U> ? U : never,
K1 extends keyof E = keyof E,
V1 extends E[K1]= E[K1]
>(collection: C, entityId: string, path: K1 | [K1]): C
export function increment<
C extends Collection<any>,
E = C extends Collection<infer U> ? U : never,
K1 extends keyof E = keyof E,
V1 = Exclude<E[K1], void>,
K2 extends keyof V1 = keyof V1,
V2 extends V1[K2]= V1[K2]
>(collection: C, entityId: string, path: K1 | [K1] | [K1, K2]): C
对于这个例子,打字非常冗长,因为它们被用来检查传入的类型
上述类型有效,唯一的问题是非数字类型的路径仍然有效。
I tried something like the below to force it to only allow numbers
export function increment<
C extends Collection<any>,
E = C extends Collection<infer U> ? U : never,
K1 extends keyof E = keyof E,
V1 extends E[K1]= E[K1]
>(collection: C, entityId: string, path: K1 | [K1]): C
export function increment<
C extends Collection<any>,
E = C extends Collection<infer U> ? U : never,
K1 extends keyof E = keyof E,
V1 = Extract<Exclude<E[K1], void>, number>, // Note the Extract
K2 extends keyof V1 = keyof V1,
V2 extends V1[K2]= V1[K2]
>(collection: C, entityId: string, path: K1 | [K1] | [K1, K2]): C
但上述并没有按预期强制执行约束
有什么想法吗?
【问题讨论】:
标签: typescript