Skip to content

Commit

Permalink
Merge pull request #31454 from microsoft/fixThisTypeIndexSignature
Browse files Browse the repository at this point in the history
Permit assignment through index signature of 'this' type
  • Loading branch information
ahejlsberg committed May 20, 2019
2 parents eeba30a + 41a3f83 commit 907664c
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 4 deletions.
12 changes: 8 additions & 4 deletions src/compiler/checker.ts
Expand Up @@ -3563,7 +3563,7 @@ namespace ts {
context.approximateLength += 6;
return createKeywordTypeNode(SyntaxKind.ObjectKeyword);
}
if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) {
if (isThisTypeParameter(type)) {
if (context.flags & NodeBuilderFlags.InObjectTypeLiteral) {
if (!context.encounteredError && !(context.flags & NodeBuilderFlags.AllowThisInObjectLiteral)) {
context.encounteredError = true;
Expand Down Expand Up @@ -10193,6 +10193,10 @@ namespace ts {
return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive | TypeFlags.Index);
}

function isThisTypeParameter(type: Type): boolean {
return !!(type.flags & TypeFlags.TypeParameter && (<TypeParameter>type).isThisType);
}

function getSimplifiedType(type: Type, writing: boolean): Type {
return type.flags & TypeFlags.IndexedAccess ? getSimplifiedIndexedAccessType(<IndexedAccessType>type, writing) :
type.flags & TypeFlags.Conditional ? getSimplifiedConditionalType(<ConditionalType>type, writing) :
Expand Down Expand Up @@ -16772,7 +16776,7 @@ namespace ts {
}

function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) {
if ((type.flags & (TypeFlags.Union | TypeFlags.Object)) || (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType)) {
if (type.flags & (TypeFlags.Union | TypeFlags.Object) || isThisTypeParameter(type)) {
const propName = escapeLeadingUnderscores(literal.text);
return filterType(type, t => isTypePresencePossible(t, propName, assumeTrue));
}
Expand Down Expand Up @@ -20092,7 +20096,7 @@ namespace ts {
return anyType;
}
if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) {
reportNonexistentProperty(right, leftType.flags & TypeFlags.TypeParameter && (leftType as TypeParameter).isThisType ? apparentType : leftType);
reportNonexistentProperty(right, isThisTypeParameter(leftType) ? apparentType : leftType);
}
return errorType;
}
Expand Down Expand Up @@ -20496,7 +20500,7 @@ namespace ts {

const effectiveIndexType = isForInVariableForNumericPropertyNames(indexExpression) ? numberType : indexType;
const accessFlags = isAssignmentTarget(node) ?
AccessFlags.Writing | (isGenericObjectType(objectType) ? AccessFlags.NoIndexSignatures : 0) :
AccessFlags.Writing | (isGenericObjectType(objectType) && !isThisTypeParameter(objectType) ? AccessFlags.NoIndexSignatures : 0) :
AccessFlags.None;
const indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, node, accessFlags) || errorType;
return checkIndexedAccessIndexType(indexedAccessType, node);
Expand Down
9 changes: 9 additions & 0 deletions tests/baselines/reference/keyofAndIndexedAccess2.errors.txt
Expand Up @@ -219,4 +219,13 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23
let x: Array<string>[K] = 'abc';
let y: ReadonlyArray<string>[K] = 'abc';
}

// Repro from #31439

export class c {
[x: string]: string;
constructor() {
this["a"] = "b";
}
}

15 changes: 15 additions & 0 deletions tests/baselines/reference/keyofAndIndexedAccess2.js
Expand Up @@ -136,6 +136,15 @@ function fn4<K extends number>() {
let x: Array<string>[K] = 'abc';
let y: ReadonlyArray<string>[K] = 'abc';
}

// Repro from #31439

export class c {
[x: string]: string;
constructor() {
this["a"] = "b";
}
}


//// [keyofAndIndexedAccess2.js]
Expand Down Expand Up @@ -226,3 +235,9 @@ function fn4() {
let x = 'abc';
let y = 'abc';
}
// Repro from #31439
export class c {
constructor() {
this["a"] = "b";
}
}
14 changes: 14 additions & 0 deletions tests/baselines/reference/keyofAndIndexedAccess2.symbols
Expand Up @@ -503,3 +503,17 @@ function fn4<K extends number>() {
>K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 133, 13))
}

// Repro from #31439

export class c {
>c : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 136, 1))

[x: string]: string;
>x : Symbol(x, Decl(keyofAndIndexedAccess2.ts, 141, 3))

constructor() {
this["a"] = "b";
>this : Symbol(c, Decl(keyofAndIndexedAccess2.ts, 136, 1))
}
}

18 changes: 18 additions & 0 deletions tests/baselines/reference/keyofAndIndexedAccess2.types
Expand Up @@ -499,3 +499,21 @@ function fn4<K extends number>() {
>'abc' : "abc"
}

// Repro from #31439

export class c {
>c : c

[x: string]: string;
>x : string

constructor() {
this["a"] = "b";
>this["a"] = "b" : "b"
>this["a"] : string
>this : this
>"a" : "a"
>"b" : "b"
}
}

9 changes: 9 additions & 0 deletions tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts
Expand Up @@ -138,3 +138,12 @@ function fn4<K extends number>() {
let x: Array<string>[K] = 'abc';
let y: ReadonlyArray<string>[K] = 'abc';
}

// Repro from #31439

export class c {
[x: string]: string;
constructor() {
this["a"] = "b";
}
}

0 comments on commit 907664c

Please sign in to comment.