如何解决Typescript:在数组中存储值时保留确切的元素类型
使用lodash合并考虑以下代码:
import { merge } from "lodash";
type Cfg = {
a: number
b: number
c: number
};
const cfg: Cfg = merge({ a: 1 },{ b: 2 },{ c: 4 });
这没有错误,因为合并功能会为所有传递的对象保留准确的类型,并且结果cfg
是所有这些类型的交集(cfg
的类型变为{a: number} & {b: number} & {c: number}
,因此它与Cfg
兼容)。如果我将merge
以外的某个属性传递给Cfg
,或者错过了某些必需的属性,则会收到错误消息。
但是现在,我需要做同样的事情,但是要事先将每个对象存储在某个地方。
类似的东西:
import { merge } from "lodash";
type Cfg = {
a: number
b: number
c: number
};
const arr: Partial<Cfg>[] = [];
function addPartial<ArgType extends Cfg>(partial: ArgType) { arr.push(partial); };
addPartial({ a: 1 });
addPartial({ b: 2 });
addPartial({ c: 3 });
const cfg: Cfg = merge(...arr);
现在,通过将数组元素的显式类型设置为Partial<Cfg>
,我将丢失确切的类型,因此,我为cfg
获得的结果类型将为Partial<Cfg>
,但当然不会满足Cfg
。
有没有办法逐步将这些部分合并起来,存储它们而不丢失其类型,从而可以证明cfg满足Cfg类型?
解决方法
简短的答案不是真的,但是具体情况有可用的解决方法。您正在按照mutating type annotation的要求索要某些东西,但尚未达到您想要的程度。
在调用任意函数之后,更改某些随机字段类型的唯一方法是将该函数设为type assertion,因此一种选择是让一个不实际使用的变量重复声明以包含该变量。然后将相关事件字段的类型用于最终合并:(playground link)
declare function merge<T>(...args: T[]): T;
// never actually used,just needed for types to accumulate every call to addPartial
const psuedo_cfg: {} = {}
type Cfg = {
a: number
b: number
c: number
};
const arr: Partial<Cfg>[] = [];
// the `| Cfg` is useful for intellisense,with just Pick<Cfg,K> intelisense doesn't know what keys are valid until they are actually given.
function addPartial<K extends keyof Cfg>(addition: Pick<Cfg,K> | Cfg,pp=psuedo_cfg): asserts pp is Pick<Cfg,K>{
arr.push(addition);
}
addPartial({a: 5},psuedo_cfg)
addPartial({b: 5},psuedo_cfg)
// addPartial({c: 5},psuedo_cfg)
const full_config: Cfg = merge(...arr) as typeof psuedo_cfg;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。