Typescript (ts2322) function returning interface Typescript(ts2322)返回接口的函数

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

Typescript (ts2322) function returning interface

问题

export interface AWSTags {
  CreatedBy: string;
  Environment: EnvironmentMap;
  Name: string;
  OwnedBy: string;
  Platform: string;
  Product: string;
  Runbook: string;
  Service: string;
}

某些其他文件具有以下方法,用于返回与接口匹配的对象。

export const getAWSTags = (stackName: string, environment: EnvironmentMap, createdBy: string): AWSTags => ({
  CreatedBy: createdBy,
  Environment: environment,
  Name: stackName,
  OwnedBy: "owner",
  Platform: "platform",
  Product: "product",
  Runbook: "url",
  Service: `${stackName}-service`,
});

为了上下文,EnvironmentMap 是一个返回三个字符串之一的类型。

当我尝试将返回值分配给 AWS 标签时,它返回 2322。

readonly tags?: {
  [key: string]: string;
};
const app = new App();
const stack = new Stack(app, stackName, {
  env: {
    account: AWS.ACCOUNT,
    region: AWS.REGION,
  },
  tags: getAWSTags(stackName, environment, 'creator'),
});
类型 'AWSTags' 无法分配给类型 '{ [key: string]: string; }'。类型 'AWSTags' 中缺少类型 'string' 的索引签名。ts(2322)

解决这个问题或提供替代方法有哪些不同的途径?

编辑:这似乎可以去除错误,但不确定其有效性。

export interface AWSTags {
  [key: string]: string;
  CreatedBy: string;
  Environment: EnvironmentMap;
  Name: string;
  OwnedBy: string;
  Platform: string;
  Product: string;
  Runbook: string;
  Service: string;
}

谢谢


<details>
<summary>英文:</summary>

export interface AWSTags {
CreatedBy: string;
Environment: EnvironmentMap;
Name: string;
OwnedBy: string;
Platform: string;
Product: string;
Runbook: string;
Service: string;
}


Some other file has this method to return an object that matches the interface.

export const getAWSTags = (stackName: string, environment: EnvironmentMap, createdBy: string): AWSTags => ({
CreatedBy: createdBy,
Environment: environment,
Name: stackName,
OwnedBy: "owner",
Platform: "platform",
Product: "product",
Runbook: "url",
Service: ${stackName}-service,
});


For context, **EnvironmentMap** is a type that returns one of three strings.

When I try to assign the return value to AWS tags, which expects the following type, it returns 2322.

readonly tags?: {
[key: string]: string;
};


const app = new App();
const stack = new Stack(app, stackName, {
env: {
account: AWS.ACCOUNT,
region: AWS.REGION,
},
tags: getAWSTags(stackName, environment, 'creator'),
});

Type 'AWSTags' is not assignable to type '{ [key: string]: string; }'. Index signature for type 'string' is missing in type 'AWSTags'.ts(2322)


What are different approaches to solve this problem or alternatives?

**EDIT**: This seems to remove the error but not sure how valid is.

export interface AWSTags {
[key: string]: string;
CreatedBy: string;
Environment: EnvironmentMap;
Name: string;
OwnedBy: string;
Platform: string;
Product: string;
Runbook: string;
Service: string;
}


Thanks

</details>


# 答案1
**得分**: 2

问题在于,尽管最终的JS代码相同,从概念上讲,您将一个对象实例传递给了一个期望一个PoJo的东西。

基本上,这个:
```ts
export interface AWSTags {
  CreatedBy: string;
  Environment: EnvironmentMap;
  Name: string;
  OwnedBy: string;
  Platform: string;
  Product: string;
  Runbook: string;
  Service: string;
}

在TS中声明了你有一个与这个声明匹配的实例,但这并不意味着你的对象将由这些值组成。

为了解决这个问题,您需要从使用接口改为只有一个简单的类型:

export type AWSTags = {
  CreatedBy: string;
  Environment: EnvironmentMap;
  Name: string;
  OwnedBy: string;
  Platform: string;
  Product: string;
  Runbook: string;
  Service: string;
}

或者,如果您想保留接口,可以在将其注入到tags之前解构结果对象:

const stack = new Stack(app, stackName, {
  // ...
  tags: {...getAWSTags(stackName, environment, 'creator')},
});
英文:

The problem is that, despite the final JS is the same, conceptually, you are passing an object instance into something that is expecting a PoJo.

Basically, this:

export interface AWSTags {
  CreatedBy: string;
  Environment: EnvironmentMap;
  Name: string;
  OwnedBy: string;
  Platform: string;
  Product: string;
  Runbook: string;
  Service: string;
}

Is declaring in TS that you have an instance that matches this declaration but this does not mean that your object will only be composed with those values.

In order to fix this, you need to change from using an interface to just having a mere type:

export type AWSTags = {
  CreatedBy: string;
  Environment: EnvironmentMap;
  Name: string;
  OwnedBy: string;
  Platform: string;
  Product: string;
  Runbook: string;
  Service: string;
}

Alternatively, if you want to keep the interface, you can deconstruct the resulting object before injecting it into tags:

const stack = new Stack(app, stackName, {
  // ...
  tags: {...getAWSTags(stackName, environment, &#39;creator&#39;)},
});

huangapple
  • 本文由 发表于 2023年2月14日 21:50:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75448804.html
匿名

发表评论

匿名网友

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

确定