给出以下内容:
class EnhancedTable extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
userID: null
};
this.deleteUserById = this.deleteUserById.bind(this);
}
componentDidMount() {
API.post("user/all", [], config).then(({ data }) => {
this.setState({
data: data.response.data.map(user => (user.id, user.name, user.email))
});
});
}
deleteUserById(n) {
console.log("user id", n);
}
render() {
return (
<TableBody>
{data.map(n => {
return (
<>
<TableCell>{n.name}</TableCell>
<TableCell>{n.email}</TableCell>
<TableCell>
<DeleteIcon
onClick={this.deleteUserById(n.id)}
className="action"
/>
</TableCell>
</>
);
})}
</TableBody>
);
}
}
我的类型type ArrayInfer<A> = A extends (infer I)[] ? I : never;
const a = ["foo", 1, {a: "foo"}];
type inferred = ArrayInfer<typeof a>;
解析为:
inferred
但是如果我稍微更改数组以包括一个空的对象常量:
type inferred = string | number | {
a: string;
}
然后const a = ["foo", 1, {}];
的类型定义中不再包含inferred
和string
:
number
那是为什么?
答案 0 :(得分:2)
似乎string
和number
都可以分配给{}
:playground(实际上,每种类型都可以分配给{}
,除了{ {1}},null
和void
)。因此,TypeScript将三种类型统一为最广泛的一种。当您遇到第一种情况时,提出的三种情况中没有一种可以使用,因此您拥有一个联合。
答案 1 :(得分:1)
要扩展@Cerberus的答案并按照@Paleo在评论中的建议,JavaScript中除Object.create(null)
,null
和undefined
以外的所有类型均以Object
为顶部以下代码段显示了祖先:
const arr = [{}, 1, 'hello', (a, b) => a+b, true, null, undefined, Object.create(null)];
function getPrototypeChain(value) {
const ancestors = [];
let proto = value;
while (proto) {
proto = Object.getPrototypeOf(proto);
if (proto) {
ancestors.push(proto.constructor.name);
}
};
return ancestors
}
arr.forEach(x => console.log(x, '->', getPrototypeChain(x).join(' -> ')));
来自TypeScript文档({@ {3}},由@jcalz在注释中建议):
从多个表达式进行类型推断时,这些表达式的类型将用于计算“最佳通用类型”。 [...] 最佳通用类型算法会考虑每种候选类型,并选择与所有其他候选类型兼容的类型。
因此,如果您使用非空对象,则列表中将找不到最佳的通用类型,并且自
找不到最佳通用类型时,得出的推论是联合数组类型
结果是所有项目类型的并集。
但是,从您在列表中包含一个空对象开始,到您没有null
或undefined
项目的那一刻,Object
便成为了最佳的通用类型和输出将是一个空对象。