TypeScript:替换对象属性类型

TypeScript:替换对象属性类型,typescript,Typescript,当我以任意数量的键合并两个对象时,属性的类型在该合并中被覆盖。我如何用打字脚本来表达这个 const a: {[propName: string]: string | number | boolean} = { a: 1, b: 2, c: true } const b: {[propName: string]: string } = { c: "2" } const c: {[propName: string]: string | number } = { ...a, .

当我以任意数量的键合并两个对象时,属性的类型在该合并中被覆盖。我如何用打字脚本来表达这个

const a: {[propName: string]: string | number | boolean} = {
  a: 1,
  b: 2, 
  c: true
}

const b: {[propName: string]: string } = {
  c: "2"
}

const c: {[propName: string]: string | number } = { ...a, ...b };

此示例显示typescript错误,即使c的类型签名是正确的。

如果像对
a
b
所做的那样,显式键入可由
字符串
索引的变量,typescript将不会跟踪在对象文本中指定的键(毕竟它们并不重要,对象可以通过任何字符串进行索引)因此它无法知道该属性将在排列中被覆盖

如果让编译器推断
a
b
的类型,则所有类型都将按预期工作:

const a = {
  a: 1,
  b: 2, 
  c: true
}

const b = {
  c: "2"
}

const c: {[propName: string]: string | number } = { ...a, ...b }; // ok now since the compiler knows that `c` in `a` will be overwritten
如果要定义受另一种类型约束的对象文字(例如,此处,它们受索引签名约束),但也要保留对象文字的实际类型,则可以使用函数来实现这一点:

function constrain<T>() {
    return function <U extends T>(o: U) {
        return o
    }
}
const a = constrain<{ [propName: string]: string | number| boolean }>()({
    a: 1,
    b: 2, 
    c: true
})

const b = constrain<{ [propName: string]: string  }>()({
    c: "2"
})

const c: {[propName: string]: string | number } = { ...a, ...b };
函数约束(){
返回函数(o:U){
返回o
}
}
常数a=约束()({
答:1,,
b:2,
c:是的
})
常数b=约束()({
c:“2”
})
常量c:{[propName:string]:string | number}={…a,…b};

如果需要在typescript中合并对象,可以使用


你有输入错误吗?它应该包括布尔值吗,比如:
const c:{[propName:string]:string | number | boolean}
?@FrankModica我相信这不是一个打字错误,他的推理是,
c
被覆盖到它并不重要,它是
bool
a
中,真的需要这个函数吗?@Danieldergross如果你想从对象文本中得到推理,并将其约束到某个东西,那么是的。但是不指定任何类型是可行的It’很好。。
var object = {
  'a': [{ 'b': 2 }, { 'd': 4 }]
};

var other = {
  'a': [{ 'c': 3 }, { 'e': 5 }]
};

_.merge(object, other);

// Output:
// { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }