Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions tests/baselines/reference/functionExpressionContextualTyping1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//// [functionExpressionContextualTyping1.ts]
enum E { red, blue }

var g0: (n: number, s:string) => number;
var g: ((s: string, w: boolean) => void) | ((n: number) => number);
var g1: ((s: string, w: boolean) => void) | ((s: string, w: number) => string);

g1 = (j, m) => { } // Per spec, no contextual signature can be extracted in this case.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain why no signature can be extracted

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain that no signature can be extracted "in the following cases".

g = (k, h=true) => { k.toLowerCase() };
g = (k) => { k.toLowerCase() };
g = (i) => {
i.toExponential();
return i;
}; // Per spec, no contextual signature can be extracted in this case.

var h: ((s: string, w: boolean) => void) | ((s: string, w: boolean) => string);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain that here a signature can be extracted and why.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the record, you can just copy/paste sections of the spec to explain what's happening, and you should feel free to.

h = (k, h) => { };

var i: typeof g0 | ((n: number, s: string) => string);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't actually use g0 anywhere else, turn the type into a type alias.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you mean to test this case out. At least move the declaration locally and name it something separate from g_

i = (foo, bar) => { return foo + 1; }
i = (foo, bar) => { return "hello"; }
var j: (name: string, num: number, boo: boolean) => void;
j = (name, number) => { };

var k: (n: E) => string = (number = 1) => { return "hello"; };
var k1: (n: {}) => string = (number = 1) => { return "hello"; };
class C<T, U> {
constructor() {
var k: ((j: T, k: U) => (T|U)[]) | ((j: number,k :U) => number[]) = (j, k) => {
return [j, k];
} // Per spec, no contextual signature can be extracted in this case.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentioning "per spec" doesn't really buy much since this is a conformance test - it should be per spec. Again, mentioning what part of the spec it refers to is more helpful.

}
}

//// [functionExpressionContextualTyping1.js]
var E;
(function (E) {
E[E["red"] = 0] = "red";
E[E["blue"] = 1] = "blue";
})(E || (E = {}));
var g0;
var g;
var g1;
g1 = function (j, m) { }; // Per spec, no contextual signature can be extracted in this case.
g = function (k, h) {
if (h === void 0) { h = true; }
k.toLowerCase();
};
g = function (k) { k.toLowerCase(); };
g = function (i) {
i.toExponential();
return i;
}; // Per spec, no contextual signature can be extracted in this case.
var h;
h = function (k, h) { };
var i;
i = function (foo, bar) { return foo + 1; };
i = function (foo, bar) { return "hello"; };
var j;
j = function (name, number) { };
var k = function (number) {
if (number === void 0) { number = 1; }
return "hello";
};
var k1 = function (number) {
if (number === void 0) { number = 1; }
return "hello";
};
var C = (function () {
function C() {
var k = function (j, k) {
return [j, k];
}; // Per spec, no contextual signature can be extracted in this case.
}
return C;
})();
167 changes: 167 additions & 0 deletions tests/baselines/reference/functionExpressionContextualTyping1.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
=== tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping1.ts ===
enum E { red, blue }
>E : E, Symbol(E, Decl(functionExpressionContextualTyping1.ts, 0, 0))
>red : E, Symbol(E.red, Decl(functionExpressionContextualTyping1.ts, 0, 8))
>blue : E, Symbol(E.blue, Decl(functionExpressionContextualTyping1.ts, 0, 13))

var g0: (n: number, s:string) => number;
>g0 : (n: number, s: string) => number, Symbol(g0, Decl(functionExpressionContextualTyping1.ts, 2, 3))
>n : number, Symbol(n, Decl(functionExpressionContextualTyping1.ts, 2, 9))
>s : string, Symbol(s, Decl(functionExpressionContextualTyping1.ts, 2, 19))

var g: ((s: string, w: boolean) => void) | ((n: number) => number);
>g : ((s: string, w: boolean) => void) | ((n: number) => number), Symbol(g, Decl(functionExpressionContextualTyping1.ts, 3, 3))
>s : string, Symbol(s, Decl(functionExpressionContextualTyping1.ts, 3, 9))
>w : boolean, Symbol(w, Decl(functionExpressionContextualTyping1.ts, 3, 19))
>n : number, Symbol(n, Decl(functionExpressionContextualTyping1.ts, 3, 45))

var g1: ((s: string, w: boolean) => void) | ((s: string, w: number) => string);
>g1 : ((s: string, w: boolean) => void) | ((s: string, w: number) => string), Symbol(g1, Decl(functionExpressionContextualTyping1.ts, 4, 3))
>s : string, Symbol(s, Decl(functionExpressionContextualTyping1.ts, 4, 10))
>w : boolean, Symbol(w, Decl(functionExpressionContextualTyping1.ts, 4, 20))
>s : string, Symbol(s, Decl(functionExpressionContextualTyping1.ts, 4, 46))
>w : number, Symbol(w, Decl(functionExpressionContextualTyping1.ts, 4, 56))

g1 = (j, m) => { } // Per spec, no contextual signature can be extracted in this case.
>g1 = (j, m) => { } : (j: any, m: any) => void
>g1 : ((s: string, w: boolean) => void) | ((s: string, w: number) => string), Symbol(g1, Decl(functionExpressionContextualTyping1.ts, 4, 3))
>(j, m) => { } : (j: any, m: any) => void
>j : any, Symbol(j, Decl(functionExpressionContextualTyping1.ts, 6, 6))
>m : any, Symbol(m, Decl(functionExpressionContextualTyping1.ts, 6, 8))

g = (k, h=true) => { k.toLowerCase() };
>g = (k, h=true) => { k.toLowerCase() } : (k: any, h?: boolean) => void
>g : ((s: string, w: boolean) => void) | ((n: number) => number), Symbol(g, Decl(functionExpressionContextualTyping1.ts, 3, 3))
>(k, h=true) => { k.toLowerCase() } : (k: any, h?: boolean) => void
>k : any, Symbol(k, Decl(functionExpressionContextualTyping1.ts, 7, 5))
>h : boolean, Symbol(h, Decl(functionExpressionContextualTyping1.ts, 7, 7))
>true : boolean
>k.toLowerCase() : any
>k.toLowerCase : any
>k : any, Symbol(k, Decl(functionExpressionContextualTyping1.ts, 7, 5))
>toLowerCase : any

g = (k) => { k.toLowerCase() };
>g = (k) => { k.toLowerCase() } : (k: any) => void
>g : ((s: string, w: boolean) => void) | ((n: number) => number), Symbol(g, Decl(functionExpressionContextualTyping1.ts, 3, 3))
>(k) => { k.toLowerCase() } : (k: any) => void
>k : any, Symbol(k, Decl(functionExpressionContextualTyping1.ts, 8, 5))
>k.toLowerCase() : any
>k.toLowerCase : any
>k : any, Symbol(k, Decl(functionExpressionContextualTyping1.ts, 8, 5))
>toLowerCase : any

g = (i) => {
>g = (i) => { i.toExponential(); return i;} : (i: any) => any
>g : ((s: string, w: boolean) => void) | ((n: number) => number), Symbol(g, Decl(functionExpressionContextualTyping1.ts, 3, 3))
>(i) => { i.toExponential(); return i;} : (i: any) => any
>i : any, Symbol(i, Decl(functionExpressionContextualTyping1.ts, 9, 5))

i.toExponential();
>i.toExponential() : any
>i.toExponential : any
>i : any, Symbol(i, Decl(functionExpressionContextualTyping1.ts, 9, 5))
>toExponential : any

return i;
>i : any, Symbol(i, Decl(functionExpressionContextualTyping1.ts, 9, 5))

}; // Per spec, no contextual signature can be extracted in this case.

var h: ((s: string, w: boolean) => void) | ((s: string, w: boolean) => string);
>h : ((s: string, w: boolean) => void) | ((s: string, w: boolean) => string), Symbol(h, Decl(functionExpressionContextualTyping1.ts, 14, 3))
>s : string, Symbol(s, Decl(functionExpressionContextualTyping1.ts, 14, 9))
>w : boolean, Symbol(w, Decl(functionExpressionContextualTyping1.ts, 14, 19))
>s : string, Symbol(s, Decl(functionExpressionContextualTyping1.ts, 14, 45))
>w : boolean, Symbol(w, Decl(functionExpressionContextualTyping1.ts, 14, 55))

h = (k, h) => { };
>h = (k, h) => { } : (k: string, h: boolean) => void
>h : ((s: string, w: boolean) => void) | ((s: string, w: boolean) => string), Symbol(h, Decl(functionExpressionContextualTyping1.ts, 14, 3))
>(k, h) => { } : (k: string, h: boolean) => void
>k : string, Symbol(k, Decl(functionExpressionContextualTyping1.ts, 15, 5))
>h : boolean, Symbol(h, Decl(functionExpressionContextualTyping1.ts, 15, 7))

var i: typeof g0 | ((n: number, s: string) => string);
>i : ((n: number, s: string) => number) | ((n: number, s: string) => string), Symbol(i, Decl(functionExpressionContextualTyping1.ts, 17, 3))
>g0 : (n: number, s: string) => number, Symbol(g0, Decl(functionExpressionContextualTyping1.ts, 2, 3))
>n : number, Symbol(n, Decl(functionExpressionContextualTyping1.ts, 17, 21))
>s : string, Symbol(s, Decl(functionExpressionContextualTyping1.ts, 17, 31))

i = (foo, bar) => { return foo + 1; }
>i = (foo, bar) => { return foo + 1; } : (foo: number, bar: string) => number
>i : ((n: number, s: string) => number) | ((n: number, s: string) => string), Symbol(i, Decl(functionExpressionContextualTyping1.ts, 17, 3))
>(foo, bar) => { return foo + 1; } : (foo: number, bar: string) => number
>foo : number, Symbol(foo, Decl(functionExpressionContextualTyping1.ts, 18, 5))
>bar : string, Symbol(bar, Decl(functionExpressionContextualTyping1.ts, 18, 9))
>foo + 1 : number
>foo : number, Symbol(foo, Decl(functionExpressionContextualTyping1.ts, 18, 5))
>1 : number

i = (foo, bar) => { return "hello"; }
>i = (foo, bar) => { return "hello"; } : (foo: number, bar: string) => string
>i : ((n: number, s: string) => number) | ((n: number, s: string) => string), Symbol(i, Decl(functionExpressionContextualTyping1.ts, 17, 3))
>(foo, bar) => { return "hello"; } : (foo: number, bar: string) => string
>foo : number, Symbol(foo, Decl(functionExpressionContextualTyping1.ts, 19, 5))
>bar : string, Symbol(bar, Decl(functionExpressionContextualTyping1.ts, 19, 9))
>"hello" : string

var j: (name: string, num: number, boo: boolean) => void;
>j : (name: string, num: number, boo: boolean) => void, Symbol(j, Decl(functionExpressionContextualTyping1.ts, 20, 3))
>name : string, Symbol(name, Decl(functionExpressionContextualTyping1.ts, 20, 8))
>num : number, Symbol(num, Decl(functionExpressionContextualTyping1.ts, 20, 21))
>boo : boolean, Symbol(boo, Decl(functionExpressionContextualTyping1.ts, 20, 34))

j = (name, number) => { };
>j = (name, number) => { } : (name: string, number: number) => void
>j : (name: string, num: number, boo: boolean) => void, Symbol(j, Decl(functionExpressionContextualTyping1.ts, 20, 3))
>(name, number) => { } : (name: string, number: number) => void
>name : string, Symbol(name, Decl(functionExpressionContextualTyping1.ts, 21, 5))
>number : number, Symbol(number, Decl(functionExpressionContextualTyping1.ts, 21, 10))

var k: (n: E) => string = (number = 1) => { return "hello"; };
>k : (n: E) => string, Symbol(k, Decl(functionExpressionContextualTyping1.ts, 23, 3))
>n : E, Symbol(n, Decl(functionExpressionContextualTyping1.ts, 23, 8))
>E : E, Symbol(E, Decl(functionExpressionContextualTyping1.ts, 0, 0))
>(number = 1) => { return "hello"; } : (number?: E) => string
>number : E, Symbol(number, Decl(functionExpressionContextualTyping1.ts, 23, 27))
>1 : number
>"hello" : string

var k1: (n: {}) => string = (number = 1) => { return "hello"; };
>k1 : (n: {}) => string, Symbol(k1, Decl(functionExpressionContextualTyping1.ts, 24, 3))
>n : {}, Symbol(n, Decl(functionExpressionContextualTyping1.ts, 24, 9))
>(number = 1) => { return "hello"; } : (number?: {}) => string
>number : {}, Symbol(number, Decl(functionExpressionContextualTyping1.ts, 24, 29))
>1 : number
>"hello" : string

class C<T, U> {
>C : C<T, U>, Symbol(C, Decl(functionExpressionContextualTyping1.ts, 24, 64))
>T : T, Symbol(T, Decl(functionExpressionContextualTyping1.ts, 25, 8))
>U : U, Symbol(U, Decl(functionExpressionContextualTyping1.ts, 25, 10))

constructor() {
var k: ((j: T, k: U) => (T|U)[]) | ((j: number,k :U) => number[]) = (j, k) => {
>k : ((j: T, k: U) => (T | U)[]) | ((j: number, k: U) => number[]), Symbol(k, Decl(functionExpressionContextualTyping1.ts, 27, 11))
>j : T, Symbol(j, Decl(functionExpressionContextualTyping1.ts, 27, 17))
>T : T, Symbol(T, Decl(functionExpressionContextualTyping1.ts, 25, 8))
>k : U, Symbol(k, Decl(functionExpressionContextualTyping1.ts, 27, 22))
>U : U, Symbol(U, Decl(functionExpressionContextualTyping1.ts, 25, 10))
>T : T, Symbol(T, Decl(functionExpressionContextualTyping1.ts, 25, 8))
>U : U, Symbol(U, Decl(functionExpressionContextualTyping1.ts, 25, 10))
>j : number, Symbol(j, Decl(functionExpressionContextualTyping1.ts, 27, 45))
>k : U, Symbol(k, Decl(functionExpressionContextualTyping1.ts, 27, 55))
>U : U, Symbol(U, Decl(functionExpressionContextualTyping1.ts, 25, 10))
>(j, k) => { return [j, k]; } : (j: any, k: any) => any[]
>j : any, Symbol(j, Decl(functionExpressionContextualTyping1.ts, 27, 77))
>k : any, Symbol(k, Decl(functionExpressionContextualTyping1.ts, 27, 79))

return [j, k];
>[j, k] : any[]
>j : any, Symbol(j, Decl(functionExpressionContextualTyping1.ts, 27, 77))
>k : any, Symbol(k, Decl(functionExpressionContextualTyping1.ts, 27, 79))

} // Per spec, no contextual signature can be extracted in this case.
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping2.ts(3,1): error TS2322: Type '(foo: number, bar: string) => boolean' is not assignable to type '((n: number, s: string) => number) | ((n: number, s: string) => string)'.
Type '(foo: number, bar: string) => boolean' is not assignable to type '(n: number, s: string) => string'.
Type 'boolean' is not assignable to type 'string'.
tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping2.ts(5,7): error TS2300: Duplicate identifier 'C'.
tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping2.ts(8,7): error TS2300: Duplicate identifier 'C'.
tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping2.ts(10,43): error TS2322: Type 'number' is not assignable to type 'T'.
tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping2.ts(10,50): error TS2322: Type 'number' is not assignable to type 'U'.


==== tests/cases/conformance/expressions/contextualTyping/functionExpressionContextualTyping2.ts (5 errors) ====
var g0: (n: number, s: string) => number
var i: typeof g0 | ((n: number, s: string) => string);
i = (foo, bar) => { return true; }
~
!!! error TS2322: Type '(foo: number, bar: string) => boolean' is not assignable to type '((n: number, s: string) => number) | ((n: number, s: string) => string)'.
!!! error TS2322: Type '(foo: number, bar: string) => boolean' is not assignable to type '(n: number, s: string) => string'.
!!! error TS2322: Type 'boolean' is not assignable to type 'string'.

class C<T> { }
~
!!! error TS2300: Duplicate identifier 'C'.

var j: (c: C<Number>) => number = (j) => { return 1; }
class C<T, U> {
~
!!! error TS2300: Duplicate identifier 'C'.
constructor() {
var k: (j: T, k: U) => (T|U)[] = (j = 1, k = 0) => {
~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'T'.
~~~~~
!!! error TS2322: Type 'number' is not assignable to type 'U'.
return [j, k];
}
}
}
36 changes: 36 additions & 0 deletions tests/baselines/reference/functionExpressionContextualTyping2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//// [functionExpressionContextualTyping2.ts]
var g0: (n: number, s: string) => number
var i: typeof g0 | ((n: number, s: string) => string);
i = (foo, bar) => { return true; }

class C<T> { }

var j: (c: C<Number>) => number = (j) => { return 1; }
class C<T, U> {
constructor() {
var k: (j: T, k: U) => (T|U)[] = (j = 1, k = 0) => {
return [j, k];
}
}
}

//// [functionExpressionContextualTyping2.js]
var g0;
var i;
i = function (foo, bar) { return true; };
var C = (function () {
function C() {
}
return C;
})();
var j = function (j) { return 1; };
var C = (function () {
function C() {
var k = function (j, k) {
if (j === void 0) { j = 1; }
if (k === void 0) { k = 0; }
return [j, k];
};
}
return C;
})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
enum E { red, blue }

var g0: (n: number, s:string) => number;
var g: ((s: string, w: boolean) => void) | ((n: number) => number);
var g1: ((s: string, w: boolean) => void) | ((s: string, w: number) => string);

g1 = (j, m) => { } // Per spec, no contextual signature can be extracted in this case.
g = (k, h=true) => { k.toLowerCase() };
g = (k) => { k.toLowerCase() };
g = (i) => {
i.toExponential();
return i;
}; // Per spec, no contextual signature can be extracted in this case.

var h: ((s: string, w: boolean) => void) | ((s: string, w: boolean) => string);
h = (k, h) => { };

var i: typeof g0 | ((n: number, s: string) => string);
i = (foo, bar) => { return foo + 1; }
i = (foo, bar) => { return "hello"; }
var j: (name: string, num: number, boo: boolean) => void;
j = (name, number) => { };

var k: (n: E) => string = (number = 1) => { return "hello"; };
var k1: (n: {}) => string = (number = 1) => { return "hello"; };
class C<T, U> {
constructor() {
var k: ((j: T, k: U) => (T|U)[]) | ((j: number,k :U) => number[]) = (j, k) => {
return [j, k];
} // Per spec, no contextual signature can be extracted in this case.
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var g0: (n: number, s: string) => number
var i: typeof g0 | ((n: number, s: string) => string);
i = (foo, bar) => { return true; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good test!


class C<T> { }

var j: (c: C<Number>) => number = (j) => { return 1; }
class C<T, U> {
constructor() {
var k: (j: T, k: U) => (T|U)[] = (j = 1, k = 0) => {
return [j, k];
}
}
}