From 3b1309d53f21e7793b708e5fc74fcf997ee92d1c Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 21 Dec 2016 14:58:44 -0800 Subject: [PATCH] Test parameter initialisation narrowing rules --- ...ameterAddsUndefinedWithStrictNullChecks.js | 37 ++++++++++++++- ...rAddsUndefinedWithStrictNullChecks.symbols | 36 ++++++++++++++- ...terAddsUndefinedWithStrictNullChecks.types | 45 ++++++++++++++++++- ...ameterAddsUndefinedWithStrictNullChecks.ts | 17 ++++++- 4 files changed, 130 insertions(+), 5 deletions(-) diff --git a/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.js b/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.js index 3e758907380..50779650c3a 100644 --- a/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.js +++ b/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.js @@ -20,12 +20,27 @@ function foo3(x = "string", b: number) { x.length; // ok, should be narrowed to string } +// .d.ts should have `T | undefined` for foo1, foo2, foo3 foo1(undefined, 1); foo2(undefined, 1); foo3(undefined, 1); -// .d.ts should have `T | undefined` for foo1, foo2, foo3 +function removeUndefinedButNotFalse(x = true) { + if (x === false) { + return x; + } +} + +declare const cond: boolean; +function removeNothing(y = cond ? true : undefined) { + if (y !== undefined) { + if (y === false) { + return y; + } + } + return true; +} //// [defaultParameterAddsUndefinedWithStrictNullChecks.js] @@ -51,10 +66,25 @@ function foo3(x, b) { if (x === void 0) { x = "string"; } x.length; // ok, should be narrowed to string } +// .d.ts should have `T | undefined` for foo1, foo2, foo3 foo1(undefined, 1); foo2(undefined, 1); foo3(undefined, 1); -// .d.ts should have `T | undefined` for foo1, foo2, foo3 +function removeUndefinedButNotFalse(x) { + if (x === void 0) { x = true; } + if (x === false) { + return x; + } +} +function removeNothing(y) { + if (y === void 0) { y = cond ? true : undefined; } + if (y !== undefined) { + if (y === false) { + return y; + } + } + return true; +} //// [defaultParameterAddsUndefinedWithStrictNullChecks.d.ts] @@ -64,3 +94,6 @@ declare let total: number; declare function foo1(x: string | undefined, b: number): void; declare function foo2(x: string | undefined, b: number): void; declare function foo3(x: string | undefined, b: number): void; +declare function removeUndefinedButNotFalse(x?: boolean | undefined): false | undefined; +declare const cond: boolean; +declare function removeNothing(y?: boolean | undefined): boolean; diff --git a/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.symbols b/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.symbols index 97cccafe103..f722ed3af26 100644 --- a/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.symbols +++ b/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.symbols @@ -68,6 +68,7 @@ function foo3(x = "string", b: number) { >length : Symbol(String.length, Decl(lib.d.ts, --, --)) } +// .d.ts should have `T | undefined` for foo1, foo2, foo3 foo1(undefined, 1); >foo1 : Symbol(foo1, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 7, 36)) >undefined : Symbol(undefined) @@ -81,5 +82,38 @@ foo3(undefined, 1); >undefined : Symbol(undefined) -// .d.ts should have `T | undefined` for foo1, foo2, foo3 +function removeUndefinedButNotFalse(x = true) { +>removeUndefinedButNotFalse : Symbol(removeUndefinedButNotFalse, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 24, 19)) +>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 27, 36)) + + if (x === false) { +>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 27, 36)) + + return x; +>x : Symbol(x, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 27, 36)) + } +} + +declare const cond: boolean; +>cond : Symbol(cond, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 33, 13)) + +function removeNothing(y = cond ? true : undefined) { +>removeNothing : Symbol(removeNothing, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 33, 28)) +>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 34, 23)) +>cond : Symbol(cond, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 33, 13)) +>undefined : Symbol(undefined) + + if (y !== undefined) { +>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 34, 23)) +>undefined : Symbol(undefined) + + if (y === false) { +>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 34, 23)) + + return y; +>y : Symbol(y, Decl(defaultParameterAddsUndefinedWithStrictNullChecks.ts, 34, 23)) + } + } + return true; +} diff --git a/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.types b/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.types index fa41973233e..15535eb435e 100644 --- a/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.types +++ b/tests/baselines/reference/defaultParameterAddsUndefinedWithStrictNullChecks.types @@ -96,6 +96,7 @@ function foo3(x = "string", b: number) { >length : number } +// .d.ts should have `T | undefined` for foo1, foo2, foo3 foo1(undefined, 1); >foo1(undefined, 1) : void >foo1 : (x: string | undefined, b: number) => void @@ -115,5 +116,47 @@ foo3(undefined, 1); >1 : 1 -// .d.ts should have `T | undefined` for foo1, foo2, foo3 +function removeUndefinedButNotFalse(x = true) { +>removeUndefinedButNotFalse : (x?: boolean | undefined) => false | undefined +>x : boolean | undefined +>true : true + + if (x === false) { +>x === false : boolean +>x : boolean +>false : false + + return x; +>x : false + } +} + +declare const cond: boolean; +>cond : boolean + +function removeNothing(y = cond ? true : undefined) { +>removeNothing : (y?: boolean | undefined) => boolean +>y : boolean | undefined +>cond ? true : undefined : true | undefined +>cond : boolean +>true : true +>undefined : undefined + + if (y !== undefined) { +>y !== undefined : boolean +>y : boolean | undefined +>undefined : undefined + + if (y === false) { +>y === false : boolean +>y : boolean +>false : false + + return y; +>y : false + } + } + return true; +>true : true +} diff --git a/tests/cases/compiler/defaultParameterAddsUndefinedWithStrictNullChecks.ts b/tests/cases/compiler/defaultParameterAddsUndefinedWithStrictNullChecks.ts index 01eefa7dd13..44f17c949e0 100644 --- a/tests/cases/compiler/defaultParameterAddsUndefinedWithStrictNullChecks.ts +++ b/tests/cases/compiler/defaultParameterAddsUndefinedWithStrictNullChecks.ts @@ -21,9 +21,24 @@ function foo3(x = "string", b: number) { x.length; // ok, should be narrowed to string } +// .d.ts should have `T | undefined` for foo1, foo2, foo3 foo1(undefined, 1); foo2(undefined, 1); foo3(undefined, 1); -// .d.ts should have `T | undefined` for foo1, foo2, foo3 +function removeUndefinedButNotFalse(x = true) { + if (x === false) { + return x; + } +} + +declare const cond: boolean; +function removeNothing(y = cond ? true : undefined) { + if (y !== undefined) { + if (y === false) { + return y; + } + } + return true; +}