采取以下打字稿:
type Primitive = undefined | null | boolean | number | string;
// A POJO is just supposed to be your typical object, with nothing
// fancy, but where we don't exactly know what's in it.
interface POJO {
[key: string]: Primitive | POJO;
}
好的,所以POJO应该代表一些通用对象,但是很简单。可能是我要JSON.stringify
或其他什么的东西。现在这是违规代码:
// Some functions implemented elsewhere...
declare function post(path: string, data: POJO): Promise<Response>;
declare function getToken(): string;
type LinkOrMessage = {link: string} | {message: string};
function specialPost(path: string, data: LinkOrMessage): Promise<Response> {
const body = {
...data,
token: getToken(),
};
// Error: see below...
return post(path, body);
}
错误是:
Argument of type '{ token: string; link: string; } | { token: string; message: string; }'
is not assignable to parameter of type 'POJO'.
Type '{ token: string; link: string; }'
is not assignable to type 'POJO'.
Index signature is missing in type '{ token: string; link: string; }'
笏?此外,如果我们更改LinkOrMessage
类型,使其不是联合,例如将其简化为{link: string}
,错误就消失了!如果我们简化为{message: string}
,则相同。所以联盟中的每个类型都可以分配给POJO
,但联盟本身不是吗?
有人可以对这种行为有所了解吗?
答案 0 :(得分:4)
由于TypeScript 2.0存在implicit index signature这样的东西,它允许您将没有索引签名的某些类型的对象分配给具有索引签名的类型的变量。但是,何时推断隐式索引签名的规则有点questionable(因为有些人质疑它们)。特别是,implicit index signatures and the spread operator之间的互动似乎正在发生一些事情。
我认为好消息可能是您看到的特定问题可能是TypeScript v2.4中引入的bug并在TypeScript v2.6.1中修复。不太好的消息是v2.6.1还没有出现;您可以尝试针对typescript@next
进行编译,看看它是否已被清除。