Skip to content

Unexpected 'undefined' error when using default parameter and exhaustive switch statement #35489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jvandort opened this issue Dec 4, 2019 · 2 comments

Comments

@jvandort
Copy link

jvandort commented Dec 4, 2019

TypeScript Version: 3.7.2

Starting in Typescript 3.7.2, some reducers that I've wrote previously have stopped compiling. When there is a default argument for the state parameter, and an exhaustive switch statement followed by a return, the compiler claims that "State | undefined" is not assignable to "State", even though the state type has a default argument. This error does not occur in Typescript 3.6.3 (see playground).

When the switch statement is not exhaustive, there is no error claiming that the final return statement can be undefined (see reducer2 in 3.7.2), but reducer in 3.7.2, which contains an exhaustive switch statement, claims that the state argument returned on the last line of the reducer may be undefined (even though there is a default argument).

This behavior is not shown in 3.6.3

Search Terms: Reducer Generic Default Argument Switch Undefined Not Assignable

Code

// Types as defined by `redux`
interface Action<T = any> {
  type: T
}

interface AnyAction extends Action {
  [extraProps: string]: any
}

type Reducer<S = any, A extends Action = AnyAction> = (
  state: S | undefined,
  action: A
) => S
// End `redux` types

type Action1 = {
  type: 'TYPE1'
};

type Action2 = {
  type: 'TYPE2'
};

type Actions = Action1 | Action2;

export const reducer: Reducer<{ status: number }, Actions> = (
    state = { status: 123 },
    action
) => {
    switch (action.type) {
      case 'TYPE1':
        return { status: 123 };
      case 'TYPE2':
        return { status: 234 };
    }
    return state;
};

export const reducer2: Reducer<{ status: number }, Actions> = (
    state = { status: 123 },
    action
) => {
    switch (action.type) {
      case 'TYPE1':
        return { status: 123 };
    }
    return state;
};

Expected behavior:

"Unreachable Code Detected" is the only error. Not " Type 'undefined' is not assignable to ''"

Actual behavior:

There are two claimed errors with this code. First, it claims the last line is unreachable (which it is, but this error does not occur in 3.6.3), and that It believes that the final return statement is of type :
"Type | undefined", when in reality, the default argument should remove the " | undefined" part.

Playground Link:
http://www.typescriptlang.org/play/#code/PTAEBUE8AcFMGdQENEBNYDMCWA7WrQAjSUAAwCd8BXAD1IChcAXWcjJAY1lAEEOmsAexwAecKAC8yHJAB8oAN71QoJjFgAuCPQC+9RjhZtO3HjL4DhoWDRY5UiC0JyLloANo2m5JAAVygtDwWvDeuADmALpaSDK6+mpwoABK1FzkIgDKktKQADS81raw9o78zjlmkE7C8lIAFG6hSCxa2QA+oFT2mLj4eW6cljhaPPQAlJLymfQgoACi9mSUqLSkqurwCeq85cIAjDlKKomaoADk4ACavvP757oA3NtJNTgATEdup1qXN-PvB46Z70U67YaIKRvQ6dN7vEE2aCCchMUAcYShUArKjpLSpVbpEQKUDNJhUYKgHBUAC2hFYoB0BTe8DqoEaKhUpO4UmJpPJWn27wAzAyBhzkHscBMpq5xfAAO5YJgcAAWbKGzgAdKdJsdxWiUNw-rd7ho3PqsbAyeQXLymC1+aBBSLgeaORxDRdrrdAWaLSpKNbbST7WSKcKACwM57ivTiwNUG0hlqwZ6u+iI5Go9E4THY9LvPFpVhE5NhrRU2n0xng5wsnLsjlco5lx3O0VujXCaUSeR6zmK5Vq+pdnDa9S6t0qD3wI3eu7nP3+hNJu0Oint12xt0rlxctPPIA

@HolgerJeromin
Copy link
Contributor

HolgerJeromin commented Dec 4, 2019

Works when you change to nightly in the menu.
So this issue is probable kind of duplicate of fixed #34661
btw 3.7.3 was released a few hours ago...

@jvandort jvandort closed this as completed Dec 4, 2019
@jvandort
Copy link
Author

jvandort commented Dec 4, 2019

Thanks for the heads up. It seems these changes aren't in 3.7.3 so I suppose they'll come around in 3.8?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants