通过枚举访问对象返回任何而不是未定义的

发布于 2025-01-23 14:58:16 字数 1800 浏览 2 评论 0原文

具有这样的结构:

enum Company {
  Google,
  Facebook
}

function getRating(company: Company) {
  const ratingMap = {
    [Company.Google]: 1000,
    [Company.Facebook]: 2000
  }

  const result = ratingMap[company]

  return result
}

打字稿理解结果号码。但是,如果我列出并非全部 company contingMap中的值,那么result具有类型。我希望ts将此表达式解析为number |未定义的而不是任何

function getRating(company: Company) {
  const ratingMap = {
    [Company.Google]: 1000,
    // [Company.Facebook]: 2000
  }

  const result = ratingMap[company] // Element implicitly has an 'any'

  return result
}

Playground

I know I can set a type for ratingMap like this:

const ratingMap: Partial<Record<Company, number>>

Playground

and it would给我预期的号码|未定义。但是我认为应该有一个更简单的优雅解决方案。也许是特定的tsconfig属性。

有什么想法如何实现这一目标?

Having a structure like this:

enum Company {
  Google,
  Facebook
}

function getRating(company: Company) {
  const ratingMap = {
    [Company.Google]: 1000,
    [Company.Facebook]: 2000
  }

  const result = ratingMap[company]

  return result
}

TypeScript understands that result is a number. But if I list not all the Company values in the ratingMap, then the result has type any. I want ts to resolve this expression into number | undefined rather than any.

function getRating(company: Company) {
  const ratingMap = {
    [Company.Google]: 1000,
    // [Company.Facebook]: 2000
  }

  const result = ratingMap[company] // Element implicitly has an 'any'

  return result
}

Playground

I know I can set a type for ratingMap like this:

const ratingMap: Partial<Record<Company, number>>

Playground

and it would give me expected number | undefined. But I think there should be a simpler elegant solution. Maybe a specific tsconfig property.

Any ideas how to achieve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤独岁月 2025-01-30 14:58:16

您是否尝试过

function getRating(company: Company): number | undefined {
  const ratingMap = {
    [Company.Google]: 1000,
    [Company.Facebook]: 2000
  }

  const result = ratingMap[company]

  return result
}

,应该会出现您想要的东西。

Have you tried

function getRating(company: Company): number | undefined {
  const ratingMap = {
    [Company.Google]: 1000,
    [Company.Facebook]: 2000
  }

  const result = ratingMap[company]

  return result
}

This should do exectly what you want.

幽蝶幻影 2025-01-30 14:58:16

使用ES6地图。 Playground here.

enum Company {
  Google,
  Facebook
}

function getRating(company: Company) {

  const ratingMap = new Map<number, number>([
  [Company.Google, 1000],
  [Company.Facebook, 2000]  
  ]);

  const result = ratingMap.get(company);
  return result
}

let ratingValue : number | undefined = getRating(Company.Google);    
alert(ratingValue);

Use the es6 map. Playground here.

enum Company {
  Google,
  Facebook
}

function getRating(company: Company) {

  const ratingMap = new Map<number, number>([
  [Company.Google, 1000],
  [Company.Facebook, 2000]  
  ]);

  const result = ratingMap.get(company);
  return result
}

let ratingValue : number | undefined = getRating(Company.Google);    
alert(ratingValue);
执笔绘流年 2025-01-30 14:58:16

结果的类型不是任何,它只是由于错误而被推断为任何。具体而言,错误是您 index 一种缺少索引签名带有0 |的数字结合1company.google的值company.facebook)分别推迟推断哪种类型contingmap是对编译器的。毫不奇怪,该类型被推断为:

const ratingMap: {
    0: number;
}

如果您启用 >向后兼容编译器标志,您会注意到,当用Company索引contingMap时,该错误消失代码>任何,因为标志简单地抑制了错误)。


You need to explicitly tell the compiler what ratingMap is: a partial record with keys of type Company and values of type number, which is trivially expressed作为partial&lt;记录&lt; company,编号&gt;结果将正确推断为号码| undefind然后:

enum Company {
  Google,
  Facebook
}

function getRating(company: Company) {
  const ratingMap: Partial<Record<Company, number>> = {
    [Company.Google]: 1000
  };

  const result = ratingMap[company]; // number | undefined

  return result;
}

playground


另一种解决方案是确保编译器company> company绝对是使用用户定义的类型守护的评级最>的关键。这可能是最类型的安全方法:

enum Company {
  Google,
  Facebook
}

const isKeyof = <T>(obj:T, key: string | number | symbol): key is keyof T => key in obj;

function getRating(company: Company) {
  const ratingMap = {
    [Company.Google]: 1000
  };

  const result = isKeyof(ratingMap, company) ?  ratingMap[company] : void 0; // number | undefined

  return result;
}

Playground

The type of the result is not any, it is just inferred as any due to the error. Specifically, the error is that you index a type that lacks an index signature with a numeric union of 0 | 1 (values of Company.Google and Company.Facebook respectively) while deferring inference of what type ratingMap is to the compiler. Unsurprisingly, the type is inferred as:

const ratingMap: {
    0: number;
}

If you enable the suppressImplicitAnyIndexErrors backwards compatibility compiler flag, you will notice that the error disappears when indexing the ratingMap with Company (although the result will still be inferred as any because the flag simply suppresses the error).


You need to explicitly tell the compiler what ratingMap is: a partial record with keys of type Company and values of type number, which is trivially expressed as Partial<Record<Company, number>>. The result type will correctly be inferred as number | undefind then:

enum Company {
  Google,
  Facebook
}

function getRating(company: Company) {
  const ratingMap: Partial<Record<Company, number>> = {
    [Company.Google]: 1000
  };

  const result = ratingMap[company]; // number | undefined

  return result;
}

Playground


An alternative solution is to ensure the compiler that company is definitely a key on the ratingMap with a user-defined type guard. This is probably the most type-safe way:

enum Company {
  Google,
  Facebook
}

const isKeyof = <T>(obj:T, key: string | number | symbol): key is keyof T => key in obj;

function getRating(company: Company) {
  const ratingMap = {
    [Company.Google]: 1000
  };

  const result = isKeyof(ratingMap, company) ?  ratingMap[company] : void 0; // number | undefined

  return result;
}

Playground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文