From cf8798d9779b2fae18dca2c319ba845dd668fa3a Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 5 Apr 2021 11:47:49 -0700 Subject: [PATCH] Make origin union cache key unique for key lists still under construction (#43339) --- src/compiler/checker.ts | 2 +- .../keyofGenericExtendingClassDoubleLayer.js | 56 +++++++++++++++++++ ...ofGenericExtendingClassDoubleLayer.symbols | 40 +++++++++++++ ...eyofGenericExtendingClassDoubleLayer.types | 31 ++++++++++ .../keyofGenericExtendingClassDoubleLayer.ts | 15 +++++ 5 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.js create mode 100644 tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.symbols create mode 100644 tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.types create mode 100644 tests/cases/compiler/keyofGenericExtendingClassDoubleLayer.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8933b241ec4..7545fd72b0a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13823,7 +13823,7 @@ namespace ts { const typeKey = !origin ? getTypeListId(types) : origin.flags & TypeFlags.Union ? `|${getTypeListId((origin).types)}` : origin.flags & TypeFlags.Intersection ? `&${getTypeListId((origin).types)}` : - `#${(origin).type.id}`; + `#${(origin).type.id}|${getTypeListId(types)}`; // origin type id alone is insufficient, as `keyof x` may resolve to multiple WIP values while `x` is still resolving const id = typeKey + getAliasId(aliasSymbol, aliasTypeArguments); let type = unionTypes.get(id); if (!type) { diff --git a/tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.js b/tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.js new file mode 100644 index 00000000000..94e732a4b4d --- /dev/null +++ b/tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.js @@ -0,0 +1,56 @@ +//// [keyofGenericExtendingClassDoubleLayer.ts] +class Model { + public createdAt: Date; +} + +type ModelAttributes = Omit; + +class AutoModel extends Model> {} + +class PersonModel extends AutoModel { + public age: number; + + toJson() { + let x: keyof this = 'createdAt'; + } +} + + +//// [keyofGenericExtendingClassDoubleLayer.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var Model = /** @class */ (function () { + function Model() { + } + return Model; +}()); +var AutoModel = /** @class */ (function (_super) { + __extends(AutoModel, _super); + function AutoModel() { + return _super !== null && _super.apply(this, arguments) || this; + } + return AutoModel; +}(Model)); +var PersonModel = /** @class */ (function (_super) { + __extends(PersonModel, _super); + function PersonModel() { + return _super !== null && _super.apply(this, arguments) || this; + } + PersonModel.prototype.toJson = function () { + var x = 'createdAt'; + }; + return PersonModel; +}(AutoModel)); diff --git a/tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.symbols b/tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.symbols new file mode 100644 index 00000000000..55bb83666e5 --- /dev/null +++ b/tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.symbols @@ -0,0 +1,40 @@ +=== tests/cases/compiler/keyofGenericExtendingClassDoubleLayer.ts === +class Model { +>Model : Symbol(Model, Decl(keyofGenericExtendingClassDoubleLayer.ts, 0, 0)) +>Attributes : Symbol(Attributes, Decl(keyofGenericExtendingClassDoubleLayer.ts, 0, 12)) + + public createdAt: Date; +>createdAt : Symbol(Model.createdAt, Decl(keyofGenericExtendingClassDoubleLayer.ts, 0, 31)) +>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --)) +} + +type ModelAttributes = Omit; +>ModelAttributes : Symbol(ModelAttributes, Decl(keyofGenericExtendingClassDoubleLayer.ts, 2, 1)) +>T : Symbol(T, Decl(keyofGenericExtendingClassDoubleLayer.ts, 4, 21)) +>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(keyofGenericExtendingClassDoubleLayer.ts, 4, 21)) +>Model : Symbol(Model, Decl(keyofGenericExtendingClassDoubleLayer.ts, 0, 0)) + +class AutoModel extends Model> {} +>AutoModel : Symbol(AutoModel, Decl(keyofGenericExtendingClassDoubleLayer.ts, 4, 47)) +>T : Symbol(T, Decl(keyofGenericExtendingClassDoubleLayer.ts, 6, 16)) +>Model : Symbol(Model, Decl(keyofGenericExtendingClassDoubleLayer.ts, 0, 0)) +>ModelAttributes : Symbol(ModelAttributes, Decl(keyofGenericExtendingClassDoubleLayer.ts, 2, 1)) +>T : Symbol(T, Decl(keyofGenericExtendingClassDoubleLayer.ts, 6, 16)) + +class PersonModel extends AutoModel { +>PersonModel : Symbol(PersonModel, Decl(keyofGenericExtendingClassDoubleLayer.ts, 6, 55)) +>AutoModel : Symbol(AutoModel, Decl(keyofGenericExtendingClassDoubleLayer.ts, 4, 47)) +>PersonModel : Symbol(PersonModel, Decl(keyofGenericExtendingClassDoubleLayer.ts, 6, 55)) + + public age: number; +>age : Symbol(PersonModel.age, Decl(keyofGenericExtendingClassDoubleLayer.ts, 8, 50)) + + toJson() { +>toJson : Symbol(PersonModel.toJson, Decl(keyofGenericExtendingClassDoubleLayer.ts, 9, 23)) + + let x: keyof this = 'createdAt'; +>x : Symbol(x, Decl(keyofGenericExtendingClassDoubleLayer.ts, 12, 11)) + } +} + diff --git a/tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.types b/tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.types new file mode 100644 index 00000000000..d3108ac94a9 --- /dev/null +++ b/tests/baselines/reference/keyofGenericExtendingClassDoubleLayer.types @@ -0,0 +1,31 @@ +=== tests/cases/compiler/keyofGenericExtendingClassDoubleLayer.ts === +class Model { +>Model : Model + + public createdAt: Date; +>createdAt : Date +} + +type ModelAttributes = Omit; +>ModelAttributes : ModelAttributes + +class AutoModel extends Model> {} +>AutoModel : AutoModel +>Model : Model> + +class PersonModel extends AutoModel { +>PersonModel : PersonModel +>AutoModel : AutoModel + + public age: number; +>age : number + + toJson() { +>toJson : () => void + + let x: keyof this = 'createdAt'; +>x : keyof this +>'createdAt' : "createdAt" + } +} + diff --git a/tests/cases/compiler/keyofGenericExtendingClassDoubleLayer.ts b/tests/cases/compiler/keyofGenericExtendingClassDoubleLayer.ts new file mode 100644 index 00000000000..8d3cbff7822 --- /dev/null +++ b/tests/cases/compiler/keyofGenericExtendingClassDoubleLayer.ts @@ -0,0 +1,15 @@ +class Model { + public createdAt: Date; +} + +type ModelAttributes = Omit; + +class AutoModel extends Model> {} + +class PersonModel extends AutoModel { + public age: number; + + toJson() { + let x: keyof this = 'createdAt'; + } +}