我有一组存储属性:
interface StoredProps {
location: boolean;
notification: boolean;
}
我还使用keyof
获取表示存储属性的字符串:
type StorableKeys = keyof StoredProps;
我有一个可以一次检索多个存储属性的函数:
const = getStoredProps<T extends StorableKeys[]>(keys: T) =>
keys.map(key => storage.get(key)).reduce((props, value, idx) => {
props[keys[idx]] = value;
return props;
}, {});
这样可行,但返回类型最终为{}
。我希望返回类型匹配由键创建的对象。
我尝试过使用{} as { [M in keyof T]: T[M] }
,但这不起作用,因为T
是一个数组类型,所以这最终会给我一个数组类型。我也试过了[M in T]
,但这是一个语法错误。
有没有办法从属性名称数组派生类型?
答案 0 :(得分:2)
也许是这样的?
const getStoredProps = <K extends StorableKeys>(keys: K[]) =>
keys.map(key => storage.get(key)).reduce((props, value, idx) => {
props[keys[idx]] = value;
return props;
}, {} as Pick<StoredProps, K>);
}
这个想法是使泛型类型只是键K
的联合而不是它们的数组,这更简单。然后keys
的类型为K[]
。实际值是返回类型Pick<StoredProps, K>
,其定义类似于{[P in K]: StoredProps[P]}
,现在可以正常工作,因为K
是键类型而不是数组类型。
您可能已经使用T extends StorableKeys[]
然后Pick<StoredProps, T[number]>
,但我不认为您真的想说T
可能是Array
的子类型{1}}。
希望有所帮助。祝你好运。