diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 25f8483a40a5a..da1af15dfa458 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1211,23 +1211,17 @@ namespace ts { // local types not visible outside the function body : false; } - if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.Variable) { - // expression inside parameter will lookup as normal variable scope when targeting es2015+ - if (compilerOptions.target && compilerOptions.target >= ScriptTarget.ES2015 && isParameter(lastLocation) && !isParameterPropertyDeclaration(lastLocation) && result.valueDeclaration.pos > lastLocation.end) { - useResult = false; - } - else if (result.flags & SymbolFlags.FunctionScopedVariable) { - // parameters are visible only inside function body, parameter list and return type - // technically for parameter list case here we might mix parameters and variables declared in function, - // however it is detected separately when checking initializers of parameters - // to make sure that they reference no variables declared after them. - useResult = + if (meaning & SymbolFlags.Value && result.flags & SymbolFlags.FunctionScopedVariable) { + // parameters are visible only inside function body, parameter list and return type + // technically for parameter list case here we might mix parameters and variables declared in function, + // however it is detected separately when checking initializers of parameters + // to make sure that they reference no variables declared after them. + useResult = lastLocation.kind === SyntaxKind.Parameter || ( lastLocation === (location).type && !!findAncestor(result.valueDeclaration, isParameter) ); - } } } else if (location.kind === SyntaxKind.ConditionalType) { diff --git a/tests/baselines/reference/genericRestParameters1.errors.txt b/tests/baselines/reference/genericRestParameters1.errors.txt index fe45ef518edf6..6b6d7f608450c 100644 --- a/tests/baselines/reference/genericRestParameters1.errors.txt +++ b/tests/baselines/reference/genericRestParameters1.errors.txt @@ -1,7 +1,11 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(22,1): error TS2556: Expected 3 arguments, but got 1 or more. tests/cases/conformance/types/rest/genericRestParameters1.ts(31,1): error TS2556: Expected 3 arguments, but got 1 or more. tests/cases/conformance/types/rest/genericRestParameters1.ts(133,40): error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. + Types of parameters 'args' and 'args' are incompatible. + Type 'any[]' is not assignable to type 'T'. tests/cases/conformance/types/rest/genericRestParameters1.ts(134,51): error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'. + Types of parameters 'args' and 'args' are incompatible. + Type 'any[]' is not assignable to type 'T'. tests/cases/conformance/types/rest/genericRestParameters1.ts(135,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. Type 'Function' provides no match for the signature '(...args: any[]): any'. tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS2322: Type '(a: never) => void' is not assignable to type '(...args: any[]) => void'. @@ -149,9 +153,13 @@ tests/cases/conformance/types/rest/genericRestParameters1.ts(164,1): error TS232 type T07 = Parameters<(...args: T) => void>; ~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '(...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. +!!! error TS2344: Types of parameters 'args' and 'args' are incompatible. +!!! error TS2344: Type 'any[]' is not assignable to type 'T'. type T08 = ConstructorParameters void>; ~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type 'new (...args: T) => void' does not satisfy the constraint 'new (...args: any[]) => any'. +!!! error TS2344: Types of parameters 'args' and 'args' are incompatible. +!!! error TS2344: Type 'any[]' is not assignable to type 'T'. type T09 = Parameters; ~~~~~~~~ !!! error TS2344: Type 'Function' does not satisfy the constraint '(...args: any[]) => any'. diff --git a/tests/baselines/reference/genericRestParameters2.errors.txt b/tests/baselines/reference/genericRestParameters2.errors.txt index 5035544c51f02..d6d3de9f32234 100644 --- a/tests/baselines/reference/genericRestParameters2.errors.txt +++ b/tests/baselines/reference/genericRestParameters2.errors.txt @@ -1,4 +1,7 @@ tests/cases/conformance/types/rest/genericRestParameters2.ts(71,40): error TS2344: Type '(x: string, ...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. + Types of parameters 'x' and 'args' are incompatible. + Type 'any[]' is not assignable to type '[string, ...any[]]'. + Property '0' is missing in type 'any[]'. ==== tests/cases/conformance/types/rest/genericRestParameters2.ts (1 errors) ==== @@ -75,6 +78,9 @@ tests/cases/conformance/types/rest/genericRestParameters2.ts(71,40): error TS234 type T05 = Parameters<(x: string, ...args: T) => void>; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '(x: string, ...args: T) => void' does not satisfy the constraint '(...args: any[]) => any'. +!!! error TS2344: Types of parameters 'x' and 'args' are incompatible. +!!! error TS2344: Type 'any[]' is not assignable to type '[string, ...any[]]'. +!!! error TS2344: Property '0' is missing in type 'any[]'. type T06 = T05<[number, ...boolean[]]>; type P1 = T extends (head: infer A, ...tail: infer B) => any ? { head: A, tail: B } : any[]; diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt index 90390fbe3a49e..ce4368081f17b 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.errors.txt @@ -1,21 +1,31 @@ +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(3,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(8,27): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(13,20): error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(21,18): error TS2372: Parameter 'a' cannot be referenced in its initializer. tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(25,22): error TS2372: Parameter 'async' cannot be referenced in its initializer. +tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts(29,15): error TS2448: Block-scoped variable 'foo' used before its declaration. -==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts (2 errors) ==== +==== tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts (6 errors) ==== let foo: string = ""; function f1 (bar = foo) { // unexpected compiler error; works at runtime + ~~~ +!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. var foo: number = 2; return bar; // returns 1 } function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime + ~~~ +!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. var foo: number = 2; return bar(); // returns 1 } function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime + ~~~ +!!! error TS2373: Initializer of parameter 'bar' cannot reference identifier 'foo' declared after it. return bar; } @@ -36,6 +46,9 @@ tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.t } function f7({[foo]: bar}: any[]) { + ~~~ +!!! error TS2448: Block-scoped variable 'foo' used before its declaration. +!!! related TS2728 tests/cases/conformance/functions/parameterInitializersForwardReferencing1_es6.ts:30:9: 'foo' is declared here. let foo: number = 2; } diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols index c0d42ab8b117d..b44c91e8afd4e 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.symbols @@ -5,7 +5,7 @@ let foo: string = ""; function f1 (bar = foo) { // unexpected compiler error; works at runtime >f1 : Symbol(f1, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 21)) >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 2, 13)) ->foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 3, 7)) var foo: number = 2; >foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 3, 7)) @@ -18,7 +18,7 @@ function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at >f2 : Symbol(f2, Decl(parameterInitializersForwardReferencing1_es6.ts, 5, 1)) >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 13)) >baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20)) ->foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 8, 7)) >baz : Symbol(baz, Decl(parameterInitializersForwardReferencing1_es6.ts, 7, 20)) var foo: number = 2; @@ -31,7 +31,7 @@ function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime >f3 : Symbol(f3, Decl(parameterInitializersForwardReferencing1_es6.ts, 10, 1)) >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 13)) ->foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 23)) >foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 12, 23)) return bar; @@ -68,7 +68,7 @@ function f6 (async = async) { function f7({[foo]: bar}: any[]) { >f7 : Symbol(f7, Decl(parameterInitializersForwardReferencing1_es6.ts, 26, 1)) ->foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 0, 3)) +>foo : Symbol(foo, Decl(parameterInitializersForwardReferencing1_es6.ts, 29, 7)) >bar : Symbol(bar, Decl(parameterInitializersForwardReferencing1_es6.ts, 28, 13)) let foo: number = 2; diff --git a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types index 009ec47ddb84c..a58d19c5755be 100644 --- a/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types +++ b/tests/baselines/reference/parameterInitializersForwardReferencing1_es6.types @@ -4,44 +4,44 @@ let foo: string = ""; >"" : "" function f1 (bar = foo) { // unexpected compiler error; works at runtime ->f1 : (bar?: string) => string ->bar : string ->foo : string +>f1 : (bar?: number) => number +>bar : number +>foo : number var foo: number = 2; >foo : number >2 : 2 return bar; // returns 1 ->bar : string +>bar : number } function f2 (bar = (baz = foo) => baz) { // unexpected compiler error; works at runtime ->f2 : (bar?: (baz?: string) => string) => string ->bar : (baz?: string) => string ->(baz = foo) => baz : (baz?: string) => string ->baz : string ->foo : string ->baz : string +>f2 : (bar?: (baz?: number) => number) => number +>bar : (baz?: number) => number +>(baz = foo) => baz : (baz?: number) => number +>baz : number +>foo : number +>baz : number var foo: number = 2; >foo : number >2 : 2 return bar(); // returns 1 ->bar() : string ->bar : (baz?: string) => string +>bar() : number +>bar : (baz?: number) => number } function f3 (bar = foo, foo = 2) { // correct compiler error, error at runtime ->f3 : (bar?: string, foo?: number) => string ->bar : string ->foo : string +>f3 : (bar?: number, foo?: number) => number +>bar : number +>foo : number >foo : number >2 : 2 return bar; ->bar : string +>bar : number } function f4 (foo, bar = foo) { @@ -74,7 +74,7 @@ function f6 (async = async) { function f7({[foo]: bar}: any[]) { >f7 : ({ [foo]: bar }: any[]) => void ->foo : string +>foo : number >bar : any let foo: number = 2;