//// [tests/cases/compiler/defaultParameterAddsUndefinedWithStrictNullChecks.ts] ////

=== defaultParameterAddsUndefinedWithStrictNullChecks.ts ===
function f(addUndefined1 = "J", addUndefined2?: number) {
>f : (addUndefined1?: string, addUndefined2?: number) => number
>  : ^             ^^^^^^^^^^^             ^^^      ^^^^^^^^^^^
>addUndefined1 : string
>              : ^^^^^^
>"J" : "J"
>    : ^^^
>addUndefined2 : number | undefined
>              : ^^^^^^^^^^^^^^^^^^

    return addUndefined1.length + (addUndefined2 || 0);
>addUndefined1.length + (addUndefined2 || 0) : number
>                                            : ^^^^^^
>addUndefined1.length : number
>                     : ^^^^^^
>addUndefined1 : string
>              : ^^^^^^
>length : number
>       : ^^^^^^
>(addUndefined2 || 0) : number
>                     : ^^^^^^
>addUndefined2 || 0 : number
>                   : ^^^^^^
>addUndefined2 : number | undefined
>              : ^^^^^^^^^^^^^^^^^^
>0 : 0
>  : ^
}
function g(addUndefined = "J", addDefined: number) {
>g : (addUndefined: string | undefined, addDefined: number) => number
>  : ^            ^^^^^^^^^^^^^^^^^^^^^^          ^^      ^^^^^^^^^^^
>addUndefined : string
>             : ^^^^^^
>"J" : "J"
>    : ^^^
>addDefined : number
>           : ^^^^^^

    return addUndefined.length + addDefined;
>addUndefined.length + addDefined : number
>                                 : ^^^^^^
>addUndefined.length : number
>                    : ^^^^^^
>addUndefined : string
>             : ^^^^^^
>length : number
>       : ^^^^^^
>addDefined : number
>           : ^^^^^^
}
let total = f() + f('a', 1) + f('b') + f(undefined, 2);
>total : number
>      : ^^^^^^
>f() + f('a', 1) + f('b') + f(undefined, 2) : number
>                                           : ^^^^^^
>f() + f('a', 1) + f('b') : number
>                         : ^^^^^^
>f() + f('a', 1) : number
>                : ^^^^^^
>f() : number
>    : ^^^^^^
>f : (addUndefined1?: string, addUndefined2?: number) => number
>  : ^             ^^^^^^^^^^^             ^^^      ^^^^^^^^^^^
>f('a', 1) : number
>          : ^^^^^^
>f : (addUndefined1?: string, addUndefined2?: number) => number
>  : ^             ^^^^^^^^^^^             ^^^      ^^^^^^^^^^^
>'a' : "a"
>    : ^^^
>1 : 1
>  : ^
>f('b') : number
>       : ^^^^^^
>f : (addUndefined1?: string, addUndefined2?: number) => number
>  : ^             ^^^^^^^^^^^             ^^^      ^^^^^^^^^^^
>'b' : "b"
>    : ^^^
>f(undefined, 2) : number
>                : ^^^^^^
>f : (addUndefined1?: string, addUndefined2?: number) => number
>  : ^             ^^^^^^^^^^^             ^^^      ^^^^^^^^^^^
>undefined : undefined
>          : ^^^^^^^^^
>2 : 2
>  : ^

total = g('c', 3) + g(undefined, 4);
>total = g('c', 3) + g(undefined, 4) : number
>                                    : ^^^^^^
>total : number
>      : ^^^^^^
>g('c', 3) + g(undefined, 4) : number
>                            : ^^^^^^
>g('c', 3) : number
>          : ^^^^^^
>g : (addUndefined: string | undefined, addDefined: number) => number
>  : ^            ^^^^^^^^^^^^^^^^^^^^^^          ^^      ^^^^^^^^^^^
>'c' : "c"
>    : ^^^
>3 : 3
>  : ^
>g(undefined, 4) : number
>                : ^^^^^^
>g : (addUndefined: string | undefined, addDefined: number) => number
>  : ^            ^^^^^^^^^^^^^^^^^^^^^^          ^^      ^^^^^^^^^^^
>undefined : undefined
>          : ^^^^^^^^^
>4 : 4
>  : ^

function foo1(x: string = "string", b: number) {
>foo1 : (x: string | undefined, b: number) => void
>     : ^ ^^      ^^^^^^^^^^^^^^ ^^      ^^^^^^^^^
>x : string
>  : ^^^^^^
>"string" : "string"
>         : ^^^^^^^^
>b : number
>  : ^^^^^^

    x.length;
>x.length : number
>         : ^^^^^^
>x : string
>  : ^^^^^^
>length : number
>       : ^^^^^^
}

function foo2(x = "string", b: number) {
>foo2 : (x: string | undefined, b: number) => void
>     : ^ ^^^^^^^^^^^^^^^^^^^^^^ ^^      ^^^^^^^^^
>x : string
>  : ^^^^^^
>"string" : "string"
>         : ^^^^^^^^
>b : number
>  : ^^^^^^

    x.length; // ok, should be string
>x.length : number
>         : ^^^^^^
>x : string
>  : ^^^^^^
>length : number
>       : ^^^^^^
}

function foo3(x: string | undefined = "string", b: number) {
>foo3 : (x: string | undefined, b: number) => void
>     : ^ ^^                  ^^ ^^      ^^^^^^^^^
>x : string | undefined
>  : ^^^^^^^^^^^^^^^^^^
>"string" : "string"
>         : ^^^^^^^^
>b : number
>  : ^^^^^^

    x.length; // ok, should be string
>x.length : number
>         : ^^^^^^
>x : string
>  : ^^^^^^
>length : number
>       : ^^^^^^

    x = undefined;
>x = undefined : undefined
>              : ^^^^^^^^^
>x : string | undefined
>  : ^^^^^^^^^^^^^^^^^^
>undefined : undefined
>          : ^^^^^^^^^
}

function foo4(x: string | undefined = undefined, b: number) {
>foo4 : (x: string | undefined, b: number) => void
>     : ^ ^^                  ^^ ^^      ^^^^^^^^^
>x : string | undefined
>  : ^^^^^^^^^^^^^^^^^^
>undefined : undefined
>          : ^^^^^^^^^
>b : number
>  : ^^^^^^

    x; // should be string | undefined
>x : string | undefined
>  : ^^^^^^^^^^^^^^^^^^

    x = undefined;
>x = undefined : undefined
>              : ^^^^^^^^^
>x : string | undefined
>  : ^^^^^^^^^^^^^^^^^^
>undefined : undefined
>          : ^^^^^^^^^
}

type OptionalNullableString = string | null | undefined;
>OptionalNullableString : OptionalNullableString
>                       : ^^^^^^^^^^^^^^^^^^^^^^

function allowsNull(val: OptionalNullableString = "") {
>allowsNull : (val?: OptionalNullableString) => void
>           : ^   ^^^                      ^^^^^^^^^
>val : OptionalNullableString
>    : ^^^^^^^^^^^^^^^^^^^^^^
>"" : ""
>   : ^^

    val = null;
>val = null : null
>           : ^^^^
>val : OptionalNullableString
>    : ^^^^^^^^^^^^^^^^^^^^^^

    val = 'string and null are both ok';
>val = 'string and null are both ok' : "string and null are both ok"
>                                    : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>val : OptionalNullableString
>    : ^^^^^^^^^^^^^^^^^^^^^^
>'string and null are both ok' : "string and null are both ok"
>                              : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
allowsNull(null); // still allows passing null
>allowsNull(null) : void
>                 : ^^^^
>allowsNull : (val?: OptionalNullableString) => void
>           : ^   ^^^                      ^^^^^^^^^



// .d.ts should have `string | undefined` for foo1, foo2, foo3 and foo4
foo1(undefined, 1);
>foo1(undefined, 1) : void
>                   : ^^^^
>foo1 : (x: string | undefined, b: number) => void
>     : ^ ^^      ^^^^^^^^^^^^^^ ^^      ^^^^^^^^^
>undefined : undefined
>          : ^^^^^^^^^
>1 : 1
>  : ^

foo2(undefined, 1);
>foo2(undefined, 1) : void
>                   : ^^^^
>foo2 : (x: string | undefined, b: number) => void
>     : ^ ^^^^^^^^^^^^^^^^^^^^^^ ^^      ^^^^^^^^^
>undefined : undefined
>          : ^^^^^^^^^
>1 : 1
>  : ^

foo3(undefined, 1);
>foo3(undefined, 1) : void
>                   : ^^^^
>foo3 : (x: string | undefined, b: number) => void
>     : ^ ^^                  ^^ ^^      ^^^^^^^^^
>undefined : undefined
>          : ^^^^^^^^^
>1 : 1
>  : ^

foo4(undefined, 1);
>foo4(undefined, 1) : void
>                   : ^^^^
>foo4 : (x: string | undefined, b: number) => void
>     : ^ ^^                  ^^ ^^      ^^^^^^^^^
>undefined : undefined
>          : ^^^^^^^^^
>1 : 1
>  : ^


function removeUndefinedButNotFalse(x = true) {
>removeUndefinedButNotFalse : (x?: boolean) => false | undefined
>                           : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>x : boolean
>  : ^^^^^^^
>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
>     : ^^^^
}

