Type ‘string’ is not assignable to type – How to type an object in array?

huangapple go评论75阅读模式
英文:

Type 'string' is not assignable to type - How to type an object in array?

问题

我有一个长数组:

  1. const allRoles = {
  2. 'product_manager': [
  3. {
  4. id: 'productManager_1',
  5. image: '/icon.png',
  6. title: 'CEO of the product',
  7. description: 'Some description.</>',
  8. },
  9. 'backend_engineer': [{...}]
  10. ...
  11. }

组件代码:

  1. // roleTitle = "Product Manager"
  2. export function OverviewModal(roleTitle: string) {
  3. const convertedRole: keyof typeof allRoles = roleTitle.toLowerCase().replace(/ /g,'_');
  4. const roleCardInfo = allRoles[convertedRole];
  5. // Tried the above but got an error:
  6. // Type 'string' is not assignable to type '"product_manager" | "backend_engineer"...'.ts(2322)

在这种情况下,这似乎不适用:
https://stackoverflow.com/questions/37978528/typescript-type-string-is-not-assignable-to-type

与类不同,我只有一个数组对象。在这种情况下,我不确定它的类型是什么。

英文:

I have a long array:

  1. const allRoles = {
  2. &#39;product_manager&#39;: [
  3. {
  4. id: &#39;productManager_1&#39;,
  5. image: &#39;/icon.png&#39;,
  6. title: &#39;CEO of the product&#39;,
  7. description: &#39;Some description&#39;.&lt;/&gt;,
  8. },
  9. &#39;backend_engineer&#39;: [{...}]
  10. ...
  11. }

Component code:

  1. // roleTitle = &quot;Product Manager&quot;
  2. export function OverviewModal(roleTitle: string) {
  3. const convertedRole: keyof typeof allRoles = roleTitle.toLowerCase().replace(/ /g,&#39;_&#39;);
  4. const roleCardInfo = allRoles[convertedRole];
  5. // Tried the above but got an error:
  6. // Type &#39;string&#39; is not assignable to type &#39;&quot;product_manager&quot; | &quot;backend_engineer&quot;...&#39;.ts(2322)

In this case, this doesn't seem to apply:
https://stackoverflow.com/questions/37978528/typescript-type-string-is-not-assignable-to-type

Instead of a class, I just have an object of arrays. I'm not sure what type it would be in this scenario.

答案1

得分: 1

这一部分你实际上在说 convertedRole 应该是 allRoles 的某个键。

  1. const convertedRole: keyof typeof allRoles

allRoles 的类型是你传递给它的值的形状。而你已经声明了你的参数 roleTitle 是一个字符串。所以字符串不是足够狭窄的类型来赋给 convertedRoleconvertedRole 只能被分配等于 allRoles 类型的键的字符串,也就是字符串 "product_manager" | "backend_engineer"...

请记住,TypeScript 不存在于运行时。它无法知道在运行代码时 roleTitle 的实际值。

英文:

So at this part you are literally saying that convertedRole should be some key of allRoles.

  1. const convertedRole: keyof typeof allRoles

the type of allRoles is the shape of the value you are giving it. And you have declared your argument roleTitle as a string. So a string is not narrow enough a type for convertedRole. convertedRole can only be assigned strings that are equal to the keys of the type of allRoles, aka the strings "product_manager" | "backend_engineer"...'.

Remember that typescript does not exist in runtime. It can not know the actual value of roleTitle as you run the code.

答案2

得分: 1

Cengen 是对的。

但是,如果您能够在编译时知道 AllRoles 的键,可能会有解决方案,就像这样:

  1. const roleTypeNames = ['product_manager', 'backend_engineer'] as const;
  2. type roleType = typeof roleTypeNames[number]
  3. const allRoles: { [key in roleType]: any } = { ... };

如果是的话,那么您可以使用类型保护。

  1. const isRoleType = (candidate: string): candidate is roleType => {
  2. for (const role of roleTypeNames) {
  3. if (role === candidate) return true;
  4. }
  5. return false;
  6. }
  7. function OverviewModal(roleTitle: string) {
  8. const sanitizedRoleTitle = roleTitle.toLowerCase().replace(/ /g, '_');
  9. if (isRoleType(sanitizedRoleTitle)) {
  10. const roleCardInfo = allRoles[sanitizedRoleTitle];
  11. }
  12. }
英文:

Cengen is right.

But, may you would have a solution to your problem if you were able to know at compile time the key of AllRoles like this :

  1. const roleTypeNames = [&#39;product_manager&#39;,&#39;backend_engineer&#39;] as const;
  2. type roleType = typeof roleTypeNames[number]
  3. const allRoles : {[key in roleType]:any} = { ...&#160;};

if yes, then you can use a typeguard.

  1. const isRoleType = (candidate : string) : candidate is roleType =&gt; {
  2. for(const role of roleTypeNames)
  3. {
  4. if(role === candidate) return true ;
  5. }
  6. return false;
  7. }
  8. function OverviewModal(roleTitle: string) {
  9. const sanitizedRoleTitle = roleTitle.toLowerCase().replace(/ /g,&#39;_&#39;);
  10. if(isRoleType(sanitizedRoleTitle))
  11. {
  12. const roleCardInfo = allRoles[sanitizedRoleTitle];
  13. }
  14. }

huangapple
  • 本文由 发表于 2023年2月8日 16:47:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75383231.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定