microsoft / microsoft/TypeScript
Idea: 'rest' index signatures and the 'error' type
还没有人认领这个 Issue。
- 主要语言
- Go
- 星标
- 111k
- 派生
- 14.3k
- 平均合并
- 2 天 4 小时
- 30 天内合并 PR
- 132
描述
[This idea is still in a relatively early stage of development, but I thought it may be of worth to someone or even for the TS team itself. Feel free to share your thoughts]
Having literal types, or unions of them, in index signatures is an idea that was brought to discussion lately (see #5683, #7656 and more general discussion in #7660):
interface Example {
[letter: "a" | "b" | "c"]: number;
}
However the conventional semantics of index signatures would imply that the type checking here would be very weak, unless noImplicitAny is enabled:
let x: Example;
x["a"] = 123; // OK
x["a"] = "ABCD"; // Error: type 'string' cannot be assigned to 'number'
x["d"] = 123; // No error with noImplicitAny disabled
x["d"] = "ABCD"; // No error with noImplicitAny disabled
x[123] = "ABCD"; // No error with noImplicitAny disabled
x[Symbol("ABCD")] = true; // No error with noImplicitAny disabled
let y = x["a"] // OK, 'y' gets type 'number'
let y = x["d"] // No error with noImplicitAny disabled, 'y' gets type 'any'
let y = x[123] // No error with noImplicitAny disabled, 'y' gets type 'any'
let y = x[Symbol("ABCD")] // No error with noImplicitAny disabled, 'y' gets type 'any'
What if it there was a way to specify the type of all the 'remaining' access keys to the interface with a special "rest" index signature (notated as [key: ...any]: T) that would set a particular type for everything other than that was specified in the interface?
interface Example {
[letter: "a" | "b" | "c"]: number;
[otherKeys: ...any]: string;
}
This may also be useful to avoid unwanted type errors when noImplicitAny is enabled:
interface Example {
[letter: "a" | "b" | "c"]: number;
[otherKeys: ...any]: any;
}
And what if it would be set to some sort of an 'error' type? I.e. a type that would not be assignable to or from anything? (perhaps except itself, still thinking about it..).
interface Example {
[letter: "a" | "b" | "c"]: number;
[otherKeys: ...any]: <Error>;
}
With the <Error> type, any assignment to or from a key that is not "a", "b" or "c" would yield an error, as it cannot be assigned to or from anything:
let x: Example;
x["a"] = 123; // OK
x["a"] = "ABCD"; // Error: type 'string' is not assignable to 'number'
x["d"] = 123; // Error: type 'number' is not assignable to '<Error>'
x["d"] = "ABCD"; // Error: type 'string' is not assignable to '<Error>'
x[123] = "ABCD"; // Error: type 'string' is not assignable to '<Error>'
x[Symbol("ABCD")] = true; // Error: type 'boolean' is not assignable to '<Error>'
let y = x["a"] // OK, 'y' gets type 'number'
let y = x["d"] // Error: type '<Error>' cannot be assigned to anything
let y = x[123] // Error: type '<Error>' cannot be assigned to anything
let y = x[Symbol("ABCD")] // Error: type '<Error>' cannot be assigned to anything
Or even:
x["d"] = <null> {}; // Error: type 'null' is not assignable to '<Error>'
x["d"] = <undefined> {}; // Error: type 'undefined' is not assignable to '<Error>'
x["d"] = <void> {}; // Error: type 'void' is not assignable to '<Error>'
x["d"] = <any> {}; // Error: type 'any' is not assignable to '<Error>'
Open questions:
- What would be the implications in terms of indexing into an entity having this signature in its type?
- What would be the implications in terms of assigning to an entity having this signature in its type?
- What would be the implications in terms of assigning from an entity having this signature in its type?
- Would adding
[key: any...]: <Error>convert any interface to a "strict" interface? (i.e. one that cannot be assigned from a 'wider' type containing more properties). And if it would, would that be seen as desirable or useful?
Edits: expanded and corrected examples to the actual behavior with noImplicitAny enabled.
Edits: converted from 'bottom' to <Error> as I seemed to have used a less common interpretation of the 'bottom' type
Edits (13 May 2016): changed [...] to [key: ...any] for better consistency with the current syntax.
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
先从此 issue 中的示例和未决问题开始,然后阅读 #5683、#7656 和 #7660 中的相关讨论。没有指定文件或测试;在确定实现范围之前,需要先确定 rest index signatures 的语义和语法以及一种错误类型,才能算完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- typescript
- 领域
- compilers
- Issue 类型
- 功能
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 停滞
- 描述清晰度
- 需要澄清
- 新手友好度
- 25/100