microsoft / microsoft/TypeScript
Object literals should have a `this` type too
还没有人认领这个 Issue。
- 主要语言
- Go
- 星标
- 111k
- 派生
- 14.3k
- 平均合并
- 2 天 4 小时
- 30 天内合并 PR
- 132
描述
TypeScript Version: 3.7.0-dev.20190831
Search Terms: this return type object composing composition
Code
I tried writing some self-contained parts of objects as a kind of multiple-inheritance or object composition, which I would combine later, and ran into this case.
const a = {
Clone() {
return this;
},
x: 1,
};
const b = {
Clone: a.Clone,
y: 2,
};
console.log(b.Clone().x); // number, bad! Should be an error!
console.log(b.Clone().y); // compiler error, bad! This should be acceptable!
Expected behavior: this, the return type of Clone, should evaluate to typeof b in b.Clone()
Actual behavior: It evaluates to typeof a, since it was defined in a
This can be circumvented by defining this as a type parameter like so:
const a = {
Clone<T>(this: T) {
return this;
},
x: 1,
}
const b = {
Clone: a.Clone,
y: 2
};
console.log(b.Clone().x); // compiler error, good!
console.log(b.Clone().y); // works! Also good!
Another interesting problem at play here though, is that using a type parameter for this also means that TS doesn't know what could be inside of this. This means you have to manually specify whatever members you hope to have access to. It would be nice if you could do T extends typeof a and it would automatically drop all the members of a in there. Right now, it will error if you do this:
'a' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.ts(7022)
I think all methods like this should, therefore, be implicitly equivalent to the following:
const a = {
Clone<T extends typeof a>(this: T) {
console.log(this.x); // should work
return this;
},
x: 1,
}
Then, b.Clone() would error since b is not a superset of a. Unless you did c = Object.assign({}, a, b), and did c.Clone()
Related Issues: https://github.com/microsoft/TypeScript/issues/29122
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从链接的 TypeScript Playground 示例开始,并比较将 Clone 从 a 复制到 b 时推断出的返回类型。阅读相关 issue #29122,了解此行为的背景。完成标准是确定并实现对象字面量方法是否应根据其所属对象的使用情况推断 this,同时保留对原始对象成员的有效访问。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- typescript
- 领域
- compilers
- Issue 类型
- 功能
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 30/100