我想使用Map而不是object map来声明一些键和值。但是Typescript似乎不支持ES6地图的索引类型,这是正确的吗?有什么解决方法吗?
此外,我还希望使值是类型安全的,以便映射中的每个条目都具有与键对应的值的正确类型。
下面是一些伪代码,它描述了我试图实现的目标:
type Keys = 'key1' | 'key2';
type Values = {
'key1': string;
'key2': number;
}
/** Should display missing entry error */
const myMap = new Map([
['key1', 'error missing key'],
]);
/** Should display wrong value type error for 'key2' */
const myMap = new Map([
['key1', 'okay'],
['key2', 'error: this value should be number'],
]);
/** Should pass */
const myMap = new Map([
['key1', 'all good'],
['key2', 42],
]);编辑:部分描述我的用例的更多代码
enum Types = {
ADD = 'ADD',
REMOVE = 'REMOVE',
};
/** I would like type-safety and autocompletion for the payload parameter */
const handleAdd = (state, payload) => ({...state, payload});
/** I would like to ensure that all types declared in Types are implemented */
export const reducers = new Map([
[Types.ADD, handleAdd],
[Types.REMOVE, handleRemove]
]);发布于 2019-02-27 22:44:19
这是我所能想象到的最接近的结果,尽管我仍然不明白为什么我们不从一开始就使用普通的对象:
type ObjectToEntries = { [K in keyof O]: [K, O[K]] }[keyof O]
interface ObjectMap {
forEach(callbackfn: (
value: O[K], key: K, map: ObjectMap
) => void, thisArg?: any): void;
get(key: K): O[K];
set(key: K, value: O[K]): this;
readonly size: number;
[Symbol.iterator](): IterableIterator>;
entries(): IterableIterator>;
keys(): IterableIterator;
values(): IterableIterator;
readonly [Symbol.toStringTag]: string;
}
interface ObjectMapConstructor {
new , K extends keyof any>(
entries: E
): ObjectMap<{ [P in E[0][0]]: Extract[1] }>;
new (): ObjectMap>;
readonly prototype: ObjectMap;
}
const ObjectMap = Map as ObjectMapConstructor;这个想法是为了制作一个新的界面,ObjectMap,它具体依赖于对象类型。O来确定它的键/值关系。然后你可以说Map构造函数可以充当ObjectMap构造函数。我还删除了可以更改实际存在的键的所有方法(以及has()方法是冗余的。true另外)。
我可以不厌其烦地解释每个方法和属性定义,但这需要大量的类型调整。简而言之,您想要使用K extends keyof O和O[K]来表示通常由K和V在Map。
构造函数更让人讨厌,因为类型推断不会以你想要的方式工作,所以保证类型安全需要两个步骤:
// let the compiler infer the type returned by the constructor
const myMapInferredType = new ObjectMap([
['key1', 'v'],
['key2', 1],
]);
// make sure it's assignable to `ObjectMap`:
const myMap: ObjectMap = myMapInferredType;如果你的myMapInferredType不匹配ObjectMap(例如,您缺少键或具有错误的值类型),然后myMap会给你带来错误。
现在您可以使用myMap作为一个ObjectMap,类似于使用Map实例,带有get()和set(),并且它应该是类型安全的。
请再次注意..。对于一个更复杂、类型更复杂、功能不比普通对象多的对象来说,这似乎是一项很大的工作。我会严肃地警告任何使用Map,它的键keyof any(即,string | number | symbol)到强consider using a plain object相反,请确保您的用例确实需要Map。
https://stackoverflow.com/questions/54907009
复制相似问题