diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 024c3d4a983..348b287f4f3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3239,9 +3239,11 @@ namespace ts { return addOptionality(getTypeFromTypeNode(declaration.type), /*optional*/ declaration.questionToken && includeOptionality); } - if (declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) && + if (compilerOptions.noImplicitAny && + declaration.kind === SyntaxKind.VariableDeclaration && !isBindingPattern(declaration.name) && !(getCombinedModifierFlags(declaration) & ModifierFlags.Export) && !isInAmbientContext(declaration)) { - // Use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no + // If --noImplicitAny is on, + // use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no // initializer or a 'null' or 'undefined' initializer. if (!(getCombinedNodeFlags(declaration) & NodeFlags.Const) && (!declaration.initializer || isNullOrUndefined(declaration.initializer))) { return autoType; diff --git a/tests/baselines/reference/controlFlowLetVar.js b/tests/baselines/reference/controlFlowLetVar.js deleted file mode 100644 index 24ad95259b1..00000000000 --- a/tests/baselines/reference/controlFlowLetVar.js +++ /dev/null @@ -1,247 +0,0 @@ -//// [controlFlowLetVar.ts] - -declare let cond: boolean; - -// CFA for 'let' with no type annotation and initializer -function f1() { - let x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined -} - -// CFA for 'let' with no type annotation and 'undefined' initializer -function f2() { - let x = undefined; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined -} - -// CFA for 'let' with no type annotation and 'null' initializer -function f3() { - let x = null; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | null -} - -// No CFA for 'let' with with type annotation -function f4() { - let x: any; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // any -} - -// CFA for 'var' with no type annotation and initializer -function f5() { - var x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined -} - -// CFA for 'var' with no type annotation and 'undefined' initializer -function f6() { - var x = undefined; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined -} - -// CFA for 'var' with no type annotation and 'null' initializer -function f7() { - var x = null; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | null -} - -// No CFA for 'var' with with type annotation -function f8() { - var x: any; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // any -} - -// No CFA for captured outer variables -function f9() { - let x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined - function f() { - const z = x; // any - } -} - -// No CFA for captured outer variables -function f10() { - let x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined - const f = () => { - const z = x; // any - }; -} - -//// [controlFlowLetVar.js] -// CFA for 'let' with no type annotation and initializer -function f1() { - var x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - var y = x; // string | number | undefined -} -// CFA for 'let' with no type annotation and 'undefined' initializer -function f2() { - var x = undefined; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - var y = x; // string | number | undefined -} -// CFA for 'let' with no type annotation and 'null' initializer -function f3() { - var x = null; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - var y = x; // string | number | null -} -// No CFA for 'let' with with type annotation -function f4() { - var x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - var y = x; // any -} -// CFA for 'var' with no type annotation and initializer -function f5() { - var x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - var y = x; // string | number | undefined -} -// CFA for 'var' with no type annotation and 'undefined' initializer -function f6() { - var x = undefined; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - var y = x; // string | number | undefined -} -// CFA for 'var' with no type annotation and 'null' initializer -function f7() { - var x = null; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - var y = x; // string | number | null -} -// No CFA for 'var' with with type annotation -function f8() { - var x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - var y = x; // any -} -// No CFA for captured outer variables -function f9() { - var x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - var y = x; // string | number | undefined - function f() { - var z = x; // any - } -} -// No CFA for captured outer variables -function f10() { - var x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - var y = x; // string | number | undefined - var f = function () { - var z = x; // any - }; -} diff --git a/tests/baselines/reference/controlFlowLetVar.symbols b/tests/baselines/reference/controlFlowLetVar.symbols deleted file mode 100644 index f58edd781b7..00000000000 --- a/tests/baselines/reference/controlFlowLetVar.symbols +++ /dev/null @@ -1,263 +0,0 @@ -=== tests/cases/compiler/controlFlowLetVar.ts === - -declare let cond: boolean; ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - -// CFA for 'let' with no type annotation and initializer -function f1() { ->f1 : Symbol(f1, Decl(controlFlowLetVar.ts, 1, 26)) - - let x; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 5, 7)) - - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = 1; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 5, 7)) - } - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = "hello"; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 5, 7)) - } - const y = x; // string | number | undefined ->y : Symbol(y, Decl(controlFlowLetVar.ts, 12, 9)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 5, 7)) -} - -// CFA for 'let' with no type annotation and 'undefined' initializer -function f2() { ->f2 : Symbol(f2, Decl(controlFlowLetVar.ts, 13, 1)) - - let x = undefined; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 17, 7)) ->undefined : Symbol(undefined) - - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = 1; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 17, 7)) - } - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = "hello"; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 17, 7)) - } - const y = x; // string | number | undefined ->y : Symbol(y, Decl(controlFlowLetVar.ts, 24, 9)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 17, 7)) -} - -// CFA for 'let' with no type annotation and 'null' initializer -function f3() { ->f3 : Symbol(f3, Decl(controlFlowLetVar.ts, 25, 1)) - - let x = null; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 29, 7)) - - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = 1; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 29, 7)) - } - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = "hello"; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 29, 7)) - } - const y = x; // string | number | null ->y : Symbol(y, Decl(controlFlowLetVar.ts, 36, 9)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 29, 7)) -} - -// No CFA for 'let' with with type annotation -function f4() { ->f4 : Symbol(f4, Decl(controlFlowLetVar.ts, 37, 1)) - - let x: any; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 41, 7)) - - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = 1; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 41, 7)) - } - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = "hello"; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 41, 7)) - } - const y = x; // any ->y : Symbol(y, Decl(controlFlowLetVar.ts, 48, 9)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 41, 7)) -} - -// CFA for 'var' with no type annotation and initializer -function f5() { ->f5 : Symbol(f5, Decl(controlFlowLetVar.ts, 49, 1)) - - var x; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 53, 7)) - - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = 1; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 53, 7)) - } - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = "hello"; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 53, 7)) - } - const y = x; // string | number | undefined ->y : Symbol(y, Decl(controlFlowLetVar.ts, 60, 9)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 53, 7)) -} - -// CFA for 'var' with no type annotation and 'undefined' initializer -function f6() { ->f6 : Symbol(f6, Decl(controlFlowLetVar.ts, 61, 1)) - - var x = undefined; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 65, 7)) ->undefined : Symbol(undefined) - - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = 1; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 65, 7)) - } - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = "hello"; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 65, 7)) - } - const y = x; // string | number | undefined ->y : Symbol(y, Decl(controlFlowLetVar.ts, 72, 9)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 65, 7)) -} - -// CFA for 'var' with no type annotation and 'null' initializer -function f7() { ->f7 : Symbol(f7, Decl(controlFlowLetVar.ts, 73, 1)) - - var x = null; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 77, 7)) - - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = 1; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 77, 7)) - } - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = "hello"; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 77, 7)) - } - const y = x; // string | number | null ->y : Symbol(y, Decl(controlFlowLetVar.ts, 84, 9)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 77, 7)) -} - -// No CFA for 'var' with with type annotation -function f8() { ->f8 : Symbol(f8, Decl(controlFlowLetVar.ts, 85, 1)) - - var x: any; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 89, 7)) - - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = 1; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 89, 7)) - } - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = "hello"; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 89, 7)) - } - const y = x; // any ->y : Symbol(y, Decl(controlFlowLetVar.ts, 96, 9)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 89, 7)) -} - -// No CFA for captured outer variables -function f9() { ->f9 : Symbol(f9, Decl(controlFlowLetVar.ts, 97, 1)) - - let x; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 101, 7)) - - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = 1; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 101, 7)) - } - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = "hello"; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 101, 7)) - } - const y = x; // string | number | undefined ->y : Symbol(y, Decl(controlFlowLetVar.ts, 108, 9)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 101, 7)) - - function f() { ->f : Symbol(f, Decl(controlFlowLetVar.ts, 108, 16)) - - const z = x; // any ->z : Symbol(z, Decl(controlFlowLetVar.ts, 110, 13)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 101, 7)) - } -} - -// No CFA for captured outer variables -function f10() { ->f10 : Symbol(f10, Decl(controlFlowLetVar.ts, 112, 1)) - - let x; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 116, 7)) - - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = 1; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 116, 7)) - } - if (cond) { ->cond : Symbol(cond, Decl(controlFlowLetVar.ts, 1, 11)) - - x = "hello"; ->x : Symbol(x, Decl(controlFlowLetVar.ts, 116, 7)) - } - const y = x; // string | number | undefined ->y : Symbol(y, Decl(controlFlowLetVar.ts, 123, 9)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 116, 7)) - - const f = () => { ->f : Symbol(f, Decl(controlFlowLetVar.ts, 124, 9)) - - const z = x; // any ->z : Symbol(z, Decl(controlFlowLetVar.ts, 125, 13)) ->x : Symbol(x, Decl(controlFlowLetVar.ts, 116, 7)) - - }; -} diff --git a/tests/baselines/reference/controlFlowLetVar.types b/tests/baselines/reference/controlFlowLetVar.types deleted file mode 100644 index 09f0ea83488..00000000000 --- a/tests/baselines/reference/controlFlowLetVar.types +++ /dev/null @@ -1,306 +0,0 @@ -=== tests/cases/compiler/controlFlowLetVar.ts === - -declare let cond: boolean; ->cond : boolean - -// CFA for 'let' with no type annotation and initializer -function f1() { ->f1 : () => void - - let x; ->x : any - - if (cond) { ->cond : boolean - - x = 1; ->x = 1 : 1 ->x : any ->1 : 1 - } - if (cond) { ->cond : boolean - - x = "hello"; ->x = "hello" : "hello" ->x : any ->"hello" : "hello" - } - const y = x; // string | number | undefined ->y : string | number | undefined ->x : string | number | undefined -} - -// CFA for 'let' with no type annotation and 'undefined' initializer -function f2() { ->f2 : () => void - - let x = undefined; ->x : any ->undefined : undefined - - if (cond) { ->cond : boolean - - x = 1; ->x = 1 : 1 ->x : any ->1 : 1 - } - if (cond) { ->cond : boolean - - x = "hello"; ->x = "hello" : "hello" ->x : any ->"hello" : "hello" - } - const y = x; // string | number | undefined ->y : string | number | undefined ->x : string | number | undefined -} - -// CFA for 'let' with no type annotation and 'null' initializer -function f3() { ->f3 : () => void - - let x = null; ->x : any ->null : null - - if (cond) { ->cond : boolean - - x = 1; ->x = 1 : 1 ->x : any ->1 : 1 - } - if (cond) { ->cond : boolean - - x = "hello"; ->x = "hello" : "hello" ->x : any ->"hello" : "hello" - } - const y = x; // string | number | null ->y : string | number | null ->x : string | number | null -} - -// No CFA for 'let' with with type annotation -function f4() { ->f4 : () => void - - let x: any; ->x : any - - if (cond) { ->cond : boolean - - x = 1; ->x = 1 : 1 ->x : any ->1 : 1 - } - if (cond) { ->cond : boolean - - x = "hello"; ->x = "hello" : "hello" ->x : any ->"hello" : "hello" - } - const y = x; // any ->y : any ->x : any -} - -// CFA for 'var' with no type annotation and initializer -function f5() { ->f5 : () => void - - var x; ->x : any - - if (cond) { ->cond : boolean - - x = 1; ->x = 1 : 1 ->x : any ->1 : 1 - } - if (cond) { ->cond : boolean - - x = "hello"; ->x = "hello" : "hello" ->x : any ->"hello" : "hello" - } - const y = x; // string | number | undefined ->y : string | number | undefined ->x : string | number | undefined -} - -// CFA for 'var' with no type annotation and 'undefined' initializer -function f6() { ->f6 : () => void - - var x = undefined; ->x : any ->undefined : undefined - - if (cond) { ->cond : boolean - - x = 1; ->x = 1 : 1 ->x : any ->1 : 1 - } - if (cond) { ->cond : boolean - - x = "hello"; ->x = "hello" : "hello" ->x : any ->"hello" : "hello" - } - const y = x; // string | number | undefined ->y : string | number | undefined ->x : string | number | undefined -} - -// CFA for 'var' with no type annotation and 'null' initializer -function f7() { ->f7 : () => void - - var x = null; ->x : any ->null : null - - if (cond) { ->cond : boolean - - x = 1; ->x = 1 : 1 ->x : any ->1 : 1 - } - if (cond) { ->cond : boolean - - x = "hello"; ->x = "hello" : "hello" ->x : any ->"hello" : "hello" - } - const y = x; // string | number | null ->y : string | number | null ->x : string | number | null -} - -// No CFA for 'var' with with type annotation -function f8() { ->f8 : () => void - - var x: any; ->x : any - - if (cond) { ->cond : boolean - - x = 1; ->x = 1 : 1 ->x : any ->1 : 1 - } - if (cond) { ->cond : boolean - - x = "hello"; ->x = "hello" : "hello" ->x : any ->"hello" : "hello" - } - const y = x; // any ->y : any ->x : any -} - -// No CFA for captured outer variables -function f9() { ->f9 : () => void - - let x; ->x : any - - if (cond) { ->cond : boolean - - x = 1; ->x = 1 : 1 ->x : any ->1 : 1 - } - if (cond) { ->cond : boolean - - x = "hello"; ->x = "hello" : "hello" ->x : any ->"hello" : "hello" - } - const y = x; // string | number | undefined ->y : string | number | undefined ->x : string | number | undefined - - function f() { ->f : () => void - - const z = x; // any ->z : any ->x : any - } -} - -// No CFA for captured outer variables -function f10() { ->f10 : () => void - - let x; ->x : any - - if (cond) { ->cond : boolean - - x = 1; ->x = 1 : 1 ->x : any ->1 : 1 - } - if (cond) { ->cond : boolean - - x = "hello"; ->x = "hello" : "hello" ->x : any ->"hello" : "hello" - } - const y = x; // string | number | undefined ->y : string | number | undefined ->x : string | number | undefined - - const f = () => { ->f : () => void ->() => { const z = x; // any } : () => void - - const z = x; // any ->z : any ->x : any - - }; -} diff --git a/tests/cases/compiler/controlFlowLetVar.ts b/tests/cases/compiler/controlFlowLetVar.ts deleted file mode 100644 index a56a3382642..00000000000 --- a/tests/cases/compiler/controlFlowLetVar.ts +++ /dev/null @@ -1,129 +0,0 @@ -// @strictNullChecks: true - -declare let cond: boolean; - -// CFA for 'let' with no type annotation and initializer -function f1() { - let x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined -} - -// CFA for 'let' with no type annotation and 'undefined' initializer -function f2() { - let x = undefined; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined -} - -// CFA for 'let' with no type annotation and 'null' initializer -function f3() { - let x = null; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | null -} - -// No CFA for 'let' with with type annotation -function f4() { - let x: any; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // any -} - -// CFA for 'var' with no type annotation and initializer -function f5() { - var x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined -} - -// CFA for 'var' with no type annotation and 'undefined' initializer -function f6() { - var x = undefined; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined -} - -// CFA for 'var' with no type annotation and 'null' initializer -function f7() { - var x = null; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | null -} - -// No CFA for 'var' with with type annotation -function f8() { - var x: any; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // any -} - -// No CFA for captured outer variables -function f9() { - let x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined - function f() { - const z = x; // any - } -} - -// No CFA for captured outer variables -function f10() { - let x; - if (cond) { - x = 1; - } - if (cond) { - x = "hello"; - } - const y = x; // string | number | undefined - const f = () => { - const z = x; // any - }; -} \ No newline at end of file