从 TypeScript 对象中删除动态键

Ngu*_*ien 4 javascript ecma ecmascript-5 typescript ecmascript-6

在 TypeScript 中,克隆一个对象非常简单:

const a = {...b}

或克隆和更新

const a = {...b, c: 'd'}

例如,我有这个代码:

const a = {
    'something': 1,
    'e': 2,
};
const c = 'something';
delete a[c];
Run Code Online (Sandbox Code Playgroud)

有没有一种很好的方法来删除该对象的属性,而不是使用传统 delete a[c]方式?(当然也不是a[c] = undefined

Ale*_* L. 12

您正在寻找计算属性名称和解构的组合。更多信息在这里

const a = {
    'something': 1,
    'e': 2,
};

const c = 'something';

const { [c]: _, ...withoutC } = a;
Run Code Online (Sandbox Code Playgroud)

在这里,我们将某些属性的值(从c变量中获取)放入_变量中,而所有其他道具都放入withoutC变量中。c定义为const允许打字稿withoutC正确推断类型的事实。


p.s*_*w.g 8

不要从 中删除属性a,而是使用解构赋值来创建一个没有该属性的新对象:

const {c, ...b} = a;
Run Code Online (Sandbox Code Playgroud)

之后b将包含aexcept的所有成员c

假设这a是某种类型,那么和{ c: string, d: string }的类型将分别被推断为和。当然,如果您必须显式编写这些类型注释,那么使用@Nurbol Alpybayev建议的类型 通常比必须以长形式拼写出类型要好得多。cbstring{ d: string }Omit

您可以c使用以下语法重命名以避免与其他名称冲突:

const {c: someOtherName, ...b} = a;
Run Code Online (Sandbox Code Playgroud)

如果您在编译时知道属性名称,则上述方法将起作用。如果您的场景并非如此,那么 TypeScript 编译器实际上无法为您提供太多帮助,因为它无法确定操作的结果类型。

您最好输入aas { [k: string]: number },在这种情况下delete a[c]就可以了,或者您可以使用如下所示的内容:

const exclude = <T>(map: { [k: string]: T }, omitted: string[]): { [k: string]: T } =>
  return Object.getOwnPropertyNames(a)
    .filter(k => omitted.indexOf(k) >= 0)
    .reduce((a, k) => (a[k] = map[k], a), {})
};
var b = exclude(a, ["c"]);
Run Code Online (Sandbox Code Playgroud)