How can I have consistent-return with exhaustive switch-case statements?

Viewed 1083

I have code like this:

function (flavors: IceCreamFlavor): 'like'|'dislike' {
    switch (flavors) {
        case IceCreamFlavor.vanilla:
            return 'dislike';
        case IceCreamFlavor.chocolate:
            return 'like';
    }
}

This is exhaustive, and I have an eslint rule that ensures exhaustiveness.

For eslint / typescript, i have the consistent-return rule switched to on, which will complain during this. I don't want to add a default (b/c if I add a new ice cream flavor, i want the developer to have to handle it), but consistent-return doesn't realize this is exhaustive and will complain.

Any ideas on how I can handle this elegantly?

3 Answers

Okay, I figured out the problem with my question.

consistent-return comes from eslint, which doesn't know about types, so there's no great way of "fixing" consistent-return to know about this.

Probably the better way of doing it is to disable consistent-return and then to use typescript-lint's explicit-function-return-type or even no-unsafe-return or something like that.

Because that would be really costly to move the whole codebase over to strongly typed functions, you could contribute a tslint rule that does consistent-return that does know about types, but if you're using ts, you probably just want to remove consistent-return.

You could siginify exhaustiveness by adding never return.

function (flavors: IceCreamFlavor): 'like'|'dislike' {
    switch (flavors) {
        case IceCreamFlavor.vanilla:
            return 'dislike';
        case IceCreamFlavor.chocolate:
            return 'like';
    }

    const _exhaustiveCheck: never = flavors;
    return _exhaustiveCheck;
}

I suggest another way:

function (flavors: IceCreamFlavor): 'like'|'dislike' {
    let flavor: string = '';
    
    switch (flavors) {
      case IceCreamFlavor.vanilla:
        flavor = 'dislike';
        break;
      case IceCreamFlavor.chocolate:
        flavor = 'like';
        break;
    }

    return flavor;
}
Related