=== tests/cases/compiler/defaultParameterAddsUndefinedWithStrictNullChecks.ts ===
function f(addUndefined1 = "J", addUndefined2?: number) {
>f : (addUndefined1?: string, addUndefined2?: number | undefined) => 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 | undefined) => number
>f('a', 1) : number
>f : (addUndefined1?: string, addUndefined2?: number | undefined) => number
>'a' : "a"
>1 : 1
>f('b') : number
>f : (addUndefined1?: string, addUndefined2?: number | undefined) => number
>'b' : "b"
>f(undefined, 2) : number
>f : (addUndefined1?: string, addUndefined2?: number | undefined) => 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
>null : null

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

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

    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
>null : null



// .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
}

