Widen object literal this types (#32240)

This commit is contained in:
Wesley Wigham
2019-07-03 15:58:21 -07:00
committed by GitHub
parent 68cb3ae136
commit 0bea4bd3c9
7 changed files with 163 additions and 14 deletions

View File

@@ -18288,7 +18288,7 @@ namespace ts {
// There was no contextual ThisType<T> for the containing object literal, so the contextual type
// for 'this' is the non-null form of the contextual type for the containing object literal or
// the type of the object literal itself.
return contextualType ? getNonNullableType(contextualType) : checkExpressionCached(containingLiteral);
return getWidenedType(contextualType ? getNonNullableType(contextualType) : checkExpressionCached(containingLiteral));
}
// In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the
// contextual type for 'this' is 'obj'.
@@ -18305,7 +18305,7 @@ namespace ts {
}
}
return checkExpressionCached(expression);
return getWidenedType(checkExpressionCached(expression));
}
}
}

View File

@@ -11,21 +11,21 @@ function createObj() {
>func1 : () => { func1(): any; func2(): any; func3(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; }; func2(): { func1(): any; func2(): any; func3(): any; }; func3(): { func1(): any; func2(): any; func3(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; }
},
func2() {
>func2 : () => { func1(): any; func2(): any; func3(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; }; func2(): { func1(): any; func2(): any; func3(): any; }; func3(): { func1(): any; func2(): any; func3(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; }
},
func3() {
>func3 : () => { func1(): any; func2(): any; func3(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; }; func2(): { func1(): any; func2(): any; func3(): any; }; func3(): { func1(): any; func2(): any; func3(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; }
}
};
}
@@ -40,63 +40,63 @@ function createObjNoCrash() {
>func1 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
},
func2() {
>func2 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
},
func3() {
>func3 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
},
func4() {
>func4 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
},
func5() {
>func5 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
},
func6() {
>func6 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
},
func7() {
>func7 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
},
func8() {
>func8 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
},
func9() {
>func9 : () => { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
return this;
>this : { func1(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func2(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func3(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func4(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func5(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func6(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func7(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func8(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; func9(): { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }; }
>this : { func1(): any; func2(): any; func3(): any; func4(): any; func5(): any; func6(): any; func7(): any; func8(): any; func9(): any; }
}
};
}

View File

@@ -0,0 +1,22 @@
tests/cases/compiler/objectLiteralThisWidenedOnUse.ts(8,21): error TS2345: Argument of type '{ prop1: number; prop2: number; prop3: number; test(): void; accept_foo(foo: Foo): boolean; }' is not assignable to parameter of type 'Foo'.
Property 'bar' is missing in type '{ prop1: number; prop2: number; prop3: number; test(): void; accept_foo(foo: Foo): boolean; }' but required in type 'Foo'.
==== tests/cases/compiler/objectLiteralThisWidenedOnUse.ts (1 errors) ====
interface Foo { bar: boolean; }
var GlobalIns = {
prop1: 1,
prop2: 2,
prop3: 3,
test () {
this.accept_foo(this);
~~~~
!!! error TS2345: Argument of type '{ prop1: number; prop2: number; prop3: number; test(): void; accept_foo(foo: Foo): boolean; }' is not assignable to parameter of type 'Foo'.
!!! error TS2345: Property 'bar' is missing in type '{ prop1: number; prop2: number; prop3: number; test(): void; accept_foo(foo: Foo): boolean; }' but required in type 'Foo'.
!!! related TS2728 tests/cases/compiler/objectLiteralThisWidenedOnUse.ts:1:17: 'bar' is declared here.
},
accept_foo (foo: Foo): boolean {
return !!foo && !!foo.bar;
}
};

View File

@@ -0,0 +1,27 @@
//// [objectLiteralThisWidenedOnUse.ts]
interface Foo { bar: boolean; }
var GlobalIns = {
prop1: 1,
prop2: 2,
prop3: 3,
test () {
this.accept_foo(this);
},
accept_foo (foo: Foo): boolean {
return !!foo && !!foo.bar;
}
};
//// [objectLiteralThisWidenedOnUse.js]
var GlobalIns = {
prop1: 1,
prop2: 2,
prop3: 3,
test: function () {
this.accept_foo(this);
},
accept_foo: function (foo) {
return !!foo && !!foo.bar;
}
};

View File

@@ -0,0 +1,39 @@
=== tests/cases/compiler/objectLiteralThisWidenedOnUse.ts ===
interface Foo { bar: boolean; }
>Foo : Symbol(Foo, Decl(objectLiteralThisWidenedOnUse.ts, 0, 0))
>bar : Symbol(Foo.bar, Decl(objectLiteralThisWidenedOnUse.ts, 0, 15))
var GlobalIns = {
>GlobalIns : Symbol(GlobalIns, Decl(objectLiteralThisWidenedOnUse.ts, 2, 3))
prop1: 1,
>prop1 : Symbol(prop1, Decl(objectLiteralThisWidenedOnUse.ts, 2, 17))
prop2: 2,
>prop2 : Symbol(prop2, Decl(objectLiteralThisWidenedOnUse.ts, 3, 11))
prop3: 3,
>prop3 : Symbol(prop3, Decl(objectLiteralThisWidenedOnUse.ts, 4, 11))
test () {
>test : Symbol(test, Decl(objectLiteralThisWidenedOnUse.ts, 5, 11))
this.accept_foo(this);
>this.accept_foo : Symbol(accept_foo, Decl(objectLiteralThisWidenedOnUse.ts, 8, 4))
>this : Symbol(GlobalIns, Decl(objectLiteralThisWidenedOnUse.ts, 2, 15))
>accept_foo : Symbol(accept_foo, Decl(objectLiteralThisWidenedOnUse.ts, 8, 4))
>this : Symbol(GlobalIns, Decl(objectLiteralThisWidenedOnUse.ts, 2, 15))
},
accept_foo (foo: Foo): boolean {
>accept_foo : Symbol(accept_foo, Decl(objectLiteralThisWidenedOnUse.ts, 8, 4))
>foo : Symbol(foo, Decl(objectLiteralThisWidenedOnUse.ts, 9, 14))
>Foo : Symbol(Foo, Decl(objectLiteralThisWidenedOnUse.ts, 0, 0))
return !!foo && !!foo.bar;
>foo : Symbol(foo, Decl(objectLiteralThisWidenedOnUse.ts, 9, 14))
>foo.bar : Symbol(Foo.bar, Decl(objectLiteralThisWidenedOnUse.ts, 0, 15))
>foo : Symbol(foo, Decl(objectLiteralThisWidenedOnUse.ts, 9, 14))
>bar : Symbol(Foo.bar, Decl(objectLiteralThisWidenedOnUse.ts, 0, 15))
}
};

View File

@@ -0,0 +1,47 @@
=== tests/cases/compiler/objectLiteralThisWidenedOnUse.ts ===
interface Foo { bar: boolean; }
>bar : boolean
var GlobalIns = {
>GlobalIns : { prop1: number; prop2: number; prop3: number; test(): void; accept_foo(foo: Foo): boolean; }
>{ prop1: 1, prop2: 2, prop3: 3, test () { this.accept_foo(this); }, accept_foo (foo: Foo): boolean { return !!foo && !!foo.bar; }} : { prop1: number; prop2: number; prop3: number; test(): void; accept_foo(foo: Foo): boolean; }
prop1: 1,
>prop1 : number
>1 : 1
prop2: 2,
>prop2 : number
>2 : 2
prop3: 3,
>prop3 : number
>3 : 3
test () {
>test : () => void
this.accept_foo(this);
>this.accept_foo(this) : boolean
>this.accept_foo : (foo: Foo) => boolean
>this : { prop1: number; prop2: number; prop3: number; test(): void; accept_foo(foo: Foo): boolean; }
>accept_foo : (foo: Foo) => boolean
>this : { prop1: number; prop2: number; prop3: number; test(): void; accept_foo(foo: Foo): boolean; }
},
accept_foo (foo: Foo): boolean {
>accept_foo : (foo: Foo) => boolean
>foo : Foo
return !!foo && !!foo.bar;
>!!foo && !!foo.bar : boolean
>!!foo : boolean
>!foo : boolean
>foo : Foo
>!!foo.bar : boolean
>!foo.bar : boolean
>foo.bar : boolean
>foo : Foo
>bar : boolean
}
};

View File

@@ -0,0 +1,14 @@
// @noImplicitThis: true
interface Foo { bar: boolean; }
var GlobalIns = {
prop1: 1,
prop2: 2,
prop3: 3,
test () {
this.accept_foo(this);
},
accept_foo (foo: Foo): boolean {
return !!foo && !!foo.bar;
}
};