【发布时间】:2022-01-06 03:31:49
【问题描述】:
谁能帮我解决这个不寻常(我认为)的问题?
最初,我正在实现类型化 Map。
export enum KeyType {
aa = 'aa',
bb = 'bb'
}
export interface ValueTypes {
aa: boolean,
bb: string
}
interface TypedMap extends Map<KeyType, ValueTypes[KeyType]> {
get<TK extends KeyType>(k: TK): ValueTypes[TK] | undefined
set<TK extends KeyType>(k: TK, v: ValueTypes[TK]): this
}
上面的代码运行良好。然后我想实现一个能够为这个地图设置多个值的函数:
function setMany<TKey, TVal> (
map: Map<TKey, TVal>,
change: (
Map<TKey, TVal> |
[TKey, TVal][]
)
): void {
const entries = change instanceof Map ? change.entries() : change
for (const [key, value] of entries) {
map.set(key, value)
}
}
如何输入[TKey, TVal][] 元组数组,以便对输入进行相应的类型检查?喜欢:
const tm = new Map() as TypedMap
setMany(
tm,
[
[KeyType.aa, 'Foo'], // Error, aa requires boolean
[KeyType.bb, 'Bar'] // Nice, bb requires string
]
)
据我了解,我需要这样的东西:
type ChangeTuple<TK extends KeyType> = [TK, ValueTypes[TK]]
但要使用参数和数组。我试过这个:
interface setManyV2 {
(
map: TypedMap,
change: (
TypedMap |
ChangeTuple[] // requires Generic type, but ChangeTuple<KeyType>[] doesn't work because TK doesn't extend anymore
)
): void
}
测试用例:
setMany(
tm,
[
[KeyType.aa, true], // correct, aa requires boolean
[KeyType.aa, false], // correct, aa requires boolean
[KeyType.bb, 'any string'], // correct bb requires string
[KeyType.aa, undefined], // incorrect, aa requires boolean, not undefined
[KeyType.aa, new Set()], // incorrect, aa requires boolean, not Set
[KeyType.aa, 'any string'], // incorrect, aa requires boolean, not string
[KeyType.bb, new Set()], // incorrect, aa requires string, not Set
[KeyType.bb, undefined], // incorrect, aa requires string, not undefined
[KeyType.bb, false], // incorrect, aa requires string, not boolean
[KeyType.bb, true] // incorrect, aa requires string, not boolean
]
)
const tm2 = new Map() as TypedMap
tm2.set(KeyType.aa, true)
tm2.set(KeyType.bb, 'string')
setMany(
tm,
tm2
)
【问题讨论】:
-
您的第一个示例导致错误
-
@captain-yossarian 谢谢,已修复
-
如果在
setManyV2接口中使用ChangeTuple<KeyType>[]会怎样? -
@Dahou 然后它将接受
[KeyType.aa | KeyType.bb, boolean | string]用于所有不可接受的元组 - 我需要[KeyType.aa, boolean]或[KeyType.bb, string]之一。
标签: typescript tuples typescript-generics type-constraints mapped-types