首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TypeScript不能将对象类型分配给Record<string,unknown>

TypeScript不能将对象类型分配给Record<string,unknown>
EN

Stack Overflow用户
提问于 2022-10-13 14:35:24
回答 2查看 40关注 0票数 0

我正在学习TypeScript,并决定尝试在我的代码库的一小部分实现它,以使球滚动。具体来说,我现在正在重构的是一个用于为Jest测试生成夹具的夹具“工厂”。

除了这些工厂,这些工厂吐出了某些对象,我还拥有一些助手方法,使生成多个对象的工作变得更容易一些。

一个工厂相当简单,它看起来像这样(值是用faker.js伪造的):

代码语言:javascript
运行
复制
function channelFactory(): ChannelItem {
  return { foo: "bar" }
}

ChannelItem只是一个简单的对象,包含一些键。

代码语言:javascript
运行
复制
interface ChannelItem { foo: string; }

作为其中一个帮助方法的例子,我有一个createMany函数,它接受一个工厂函数和一个Count作为参数

代码语言:javascript
运行
复制
function createMany(factory: () => Record<string, unknown>, count = 1): Record<string, any>[] {
  // A for loop that calls the factory, pushes those into an array and returns that array
}

但是,如果我试图在某个地方使用这些工厂,例如在将一些创建的通道持久化到DB的函数中,我会得到TS编译器警告我,Record<string, any>[]不能分配给ChannelItem[]

代码语言:javascript
运行
复制
function saveChannels(payload: ChannelItem[]): void { // Unimportant implementation details }
代码语言:javascript
运行
复制
const items = createMany(channelFactory, 5);
saveChannels(items) // => Argument type Record<string, any>[] is not assignable to parameter type ChannelItem[]   Type Record<string, any> is not assignable to type ChannelItem 

我知道这是一个常见的接口问题(#15300问题),可能的解决方案是声明一个type而不是一个interface,但是在这种情况下,我仍然会收到同样的警告。

代码语言:javascript
运行
复制
type ChannelItem = { foo: string } // Still gives me the above warning

让我的factory函数更通用的理想方法是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-13 14:46:24

您可以使createMany函数成为通用函数:

代码语言:javascript
运行
复制
function createMany<K extends string, T>(factory: () => Record<K, T>, count = 1): Record<K, T>[] {
  const arr = [];
  for (let i = 0; i < count; i++) {
    arr.push(factory());
  }
  return arr;
}

const items = createMany(channelFactory, 5);

console.log(items);
// Prints:
//[
//  { foo: 'bar' },
//  { foo: 'bar' },
//  { foo: 'bar' },
//  { foo: 'bar' },
//  { foo: 'bar' }
//]

我之所以创建K extends string,是因为您指定希望您的记录具有字符串键。你想做什么都行。

只需自己填写这些功能,不确定你想要做些什么。

票数 1
EN

Stack Overflow用户

发布于 2022-10-13 14:57:18

createMany甚至不需要知道factory返回的类型。

您可以使它具有更大的灵活性。

代码语言:javascript
运行
复制
interface ChannelItem { foo: string; }
function channelFactory(): ChannelItem {
  return { foo: "bar" }
}

function createMany<T>(factory: () => T, count = 1): T[] {
  // A for loop that calls the factory, pushes those into an array and returns that array
  return []
}

function saveChannels(payload: ChannelItem[]): void {  }

const items = createMany(channelFactory, 5);
saveChannels(items)

TS游乐场

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74057601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档