如何通过详尽的 switch-case 语句获得一致的返回?

问题描述 投票:0回答:5

我有这样的代码:

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

这是详尽的,我有一个 eslint 规则来确保详尽。

对于 eslint / typescript,我将

consistent-return
规则切换为打开状态,在此期间会抱怨。我不想想添加默认值(b/c如果我添加新的冰淇淋口味,我希望开发人员必须处理它),但一致性返回并没有意识到这是详尽无遗的,并且会抱怨。

关于如何优雅地处理这个问题有什么想法吗?

typescript eslint typescript-eslint
5个回答
13
投票

好吧,我的问题解决了。

consistent-return
来自 eslint,它不了解类型,因此没有很好的方法来“修复”一致返回来了解这一点。

可能更好的方法是禁用

consistent-return
,然后使用 typescript-lint
explicit-function-return-type
甚至
no-unsafe-return
或类似的东西。

因为将整个代码库转移到强类型函数的成本确实很高,所以您可以贡献一个 tslint 规则来

consistent-return
does 了解类型,但如果您使用 ts,您可能只想删除
consistent-return.


5
投票

可能为时已晚,无法帮助OP,但对于任何未来的读者: TS 配置选项

noImplicitReturns
提供了 ESLint
consistent-return
的所有优点,同时还支持详尽的开关/等。因为它具有类型感知能力。

供参考:


3
投票

您可以通过添加

never
返回来表示详尽。

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

    const _exhaustiveCheck: never = flavors;
    return _exhaustiveCheck;
}

1
投票

我刚刚花了一些时间找出解决方案,但这可能有点矫枉过正。我重构了 switch 语句以使用地图:

type ButtonSize = 'large' | 'medium' | 'small';

// BEFORE (w/ switch statement)
function getSizeStyles(size: ButtonSize) {
  switch (size) {
    case 'large':
      return 'justify-start text-xl px-6 py-4 min-w-[320px]';
    case 'medium':
      return 'justify-center text-lg px-4 py-2 min-w-[150px]';
    case 'small':
      return 'justify-center text-sm px-2 py-1';
  }
}

// REFACTOR (uses a new "StyleMap")
type StyleMap<T extends string> = {
  [K in T]: string;
};

function getSizeStyles(size: ButtonSize) {
  const styles: StyleMap<ButtonSize> = {
    large: 'justify-start text-xl px-6 py-4 min-w-[320px]',
    medium: 'justify-center text-lg px-4 py-2 min-w-[150px]',
    small: 'justify-center text-sm px-2 py-1',
  };

  return styles[size];
}


-1
投票

我建议另一种方式:

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

    return flavor;
}
© www.soinside.com 2019 - 2024. All rights reserved.