下面,我有一个函数,该函数返回带有2个对象的元组。
const example = () => {
return [{meow: true}, { woof: false}]
}
const [catStuff, dogStuff] = example()
catStuff.meow // why is this possibly undefined? why does this possibly contain `woof`?
我很好奇为什么会有工会?我如何获得该元组以返回两个不同的对象?
catStuff: {
meow: boolean,
woof?: undefined
} | {
woof: boolean,
meow?: undefined
}
答案 0 :(得分:1)
您可以使用以下
function tuple<T extends any[]>(...args: T): T {
return args;
}
const example = () => {
return tuple({meow: true}, { woof: false})
}
编译器正确推断:
const example: () => [{
meow: boolean;
}, {
woof: boolean;
}]
我从Tuples in rest parameters and spread expressions #24897获得了tuple
功能
对于只读元组,可以使用:
const example = () => {
return [{meow: true}, { woof: false}] as const;
}
在这里,编译器推断
const example: () => readonly [{
readonly meow: true;
}, {
readonly woof: false;
}]
答案 1 :(得分:0)
您问为什么。这取决于您要如何处理结果。就Typescript而言,您的元组可以解释为
[typescript]元素隐式具有“ any”类型,因为类型为“ { 喵woof ?:未定义; } | {woof:boolean;喵?: 未定义}'。
例如,以下和类似用法应该可以正常工作:
const example = () => {
return [{meow: true}, { woof: false}]
}
const [catStuff, dogStuff] = example()
console.log(`${catStuff.meow}`)
console.log(`${dogStuff.woof}`)
以下内容无效
console.log(`${dogStuff.meow}`)
console.log(`${catStuff.woof}`)
之所以编译catStuff.woof
是因为Typescript仅检查元组中是否存在woof
;它不会检查与之关联的元素。但是在运行时,由于未为woof
定义catStuff
,因此您会得到一个undefined
。
以下内容将不会编译,因为元组/对象类型中不存在speak
:
console.log(`${catStuff.speak}`)
答案 2 :(得分:0)
这与example
是一个函数无关;如果直接将返回值定义为常量,则会得到相同的推论:
const c = [{ meow: true }, { woof: false }];
// c: ({ meow: boolean, woof?: undefined } | { woof: boolean, meow?: undefined })[]
根本原因是Typescript推断文字数组具有数组类型,即使它可以推断更具体的元组类型也是如此。这是2017年在Typescript问题跟踪器上的raised as an issue,但该问题已关闭且未采取任何措施。这可能是因为as one commenter noted
推断元组类型确实是不安全的。在其他问题上对此有很多讨论。当某人正在使用他们不打算成为元组的数组时,它将并且可能破坏很多其他代码。 ...仅仅因为数组文字是const并且是异构的,并不意味着它打算成为一个元组。特别是因为即使使用元组类型,所有运行时数组功能都可用。
也就是说,即使将c
声明为对数组的const
引用,c
的内容仍可以由其他代码更改,例如c.pop()
,因此通常假设c
始终按此顺序始终具有这两种不同类型的两个元素,这通常是不安全的。
如果您希望函数example
具有不同的返回类型,只需添加一个显式类型注释:
type MeowWoof = [{ meow: boolean }, { woof: boolean }];
const example: () => MeowWoof = () => {
return [{ meow: true }, { woof: false }]
};
还请注意,c
的最具体可能的类型是[{ meow: true }, { woof: false }]
,而不是[{ meow: boolean }, { woof: boolean }]
。