组件 props 中的函数参数不兼容

2024-02-09

我有一个组件,它接受一个项目列表,已知有一个 ID,以及一个过滤这些项目的函数。

具有 ID 的类型是项目的通用类型,所有项目都将具有。

但更具体的项目将包括其他道具。

type GenericItem = {
    id: string;
}

type SpecificItem = {
    id: string;
    someOtherProp: boolean;
}

我还有一个函数类型,它使用泛型类型进行操作。

type GenericItemFunction = (item: GenericItem) => boolean;

然后,我有了这个在其 props 中使用 GenericItem 和 GenericItemFunction 的组件。

type CompProps = {
    fn: GenericItemFunction;
    items: GenericItem[];
}
const Comp: React.FC<CompProps> = ({ fn, items }) => <></>;

当我尝试将此组件与特定类型一起使用时,我收到错误消息,指出我无法使用 GenericItemFunction 的实现,因为项目的类型不兼容。

const App = () => {
    const items: SpecificItem[] = [];
    const filter = (item: SpecificItem) => item.someOtherProp;

    return (
        <Comp
            fn={filter}     // error on `fn` prop
            items={items}
        />
    )
}

我收到的打字稿错误是:

Type '(item: SpecificItem) => boolean' is not assignable to type 'GenericItemFunction'.
  Types of parameters 'item' and 'item' are incompatible.
    Property 'someOtherProp' is missing in type 'GenericItem' but required in type 'SpecificItem'.

我想我有两个问题;

首先,当两种类型都期望时,为什么会发生冲突id: string财产?

其次,有没有更明智的方法来做这样的事情?

我的第一个是类型item on the GenericItemFunction可以从提供给的值推断出itemsApp 组件中的 prop。

但说实话,我不确定那会是什么样子......

我的另一个想法是Comp是一个泛型,但没有显示使用使用泛型的 React 组件...似乎 jsx/tsx 并不真正支持该语法。

我希望这样的事情会引发各种错误。

const Comp = <T extends GenericItem,>({ fn, items }) => <></>;

const App = () => {
 return <Comp<SpecificType> />;
}

最后我尝试了一下,没有出现任何错误。但缺点是类型items被推断为任意。

type GenericItem = {
    id: string;
}

type SpecificItem = {
    id: string;
    someOtherProp: boolean;
}

type GenericItemFunction <T> = (item: T) => boolean;


type CompProps <T extends GenericItem = any> = {
    fn: GenericItemFunction<T>;
    items: T[];
}
const Comp: React.FC<CompProps> = ({ fn, items }) => <></>;

const App = () => {
    const items: SpecificItem[] = [];
    const filter = (item: SpecificItem) => item.someOtherProp;

    return (
        <Comp
            fn={filter}
            items={items}
        />
    )
}

这是我一直在使用的游乐场的链接。

https://www.typescriptlang.org/play?#code/C4TwDgpgBA4hB2EBOBLAxgSWBAtlAvFAN4BQAkCgCYBcUAzsKvAOYDcJAviSaJFAMqQ0KAGbosuAsRJRZUKrQZM2MuXQD2OCAHlgAC2QAFJOrC0ARuvUAbCAEN47Lj3DQ4iVJmw4AYgF d4NGAUdXgoAB4AFQA+KQAKFG9aSIBKAljLG3tHbhc+AGFNMGNTOgjIqAgAD2x4SjL3ZHFvKQcQWMJSMhF4WkbPCV8AoJD4KOj2OXlvOmSAbQBdJxI0UIYoQpwzKAAleyCAOh988M3ikzA6Dqg4oigegBpp3 DKONPxY8OjwgHoJ7lW8HWAEEwGB4u9YqQpoD1okXrRBBBhGIvLhFlJFpM5LDgPcUNZsEh4vCcIihKJmrhIc8cAcNFpdAYkCUwOxVLIkBBgH4kGE4hyphEzoKhXIevgiGJCcguGKxaS6JLFXL5X9BSlO EA https://www.typescriptlang.org/play?#code/C4TwDgpgBA4hB2EBOBLAxgSWBAtlAvFAN4BQAkCgCYBcUAzsKvAOYDcJAviSaJFAMqQ0KAGbosuAsRJRZUKrQZM2MuXQD2OCAHlgAC2QAFJOrC0ARuvUAbCAEN47Lj3DQ4iVJmw4AYgFd4NGAUdXgoAB4AFQA+KQAKFG9aSIBKAljLG3tHbhc+AGFNMGNTOgjIqAgAD2x4SjL3ZHFvKQcQWMJSMhF4WkbPCV8AoJD4KOj2OXlvOmSAbQBdJxI0UIYoQpwzKAAleyCAOh988M3ikzA6Dqg4oigegBpp3DKONPxY8OjwgHoJ7lW8HWAEEwGB4u9YqQpoD1okXrRBBBhGIvLhFlJFpM5LDgPcUNZsEh4vCcIihKJmrhIc8cAcNFpdAYkCUwOxVLIkBBgH4kGE4hyphEzoKhXIevgiGJCcguGKxaS6JLFXL5X9BSlOEA

UPDATE:

为什么使用 any 作为 GenericItem 类型的默认值?如果没有这个,我相信它应该正确地从 GenericItemFunction 推断出 Genericitem 。 – tymzap

删除= any为了CompPropstypedef 导致错误Comp宣言...

type CompProps <T extends GenericItem> = {
    fn: GenericItemFunction<T>;
    items: T[];
}
const Comp: React.FC<CompProps> = ({ fn, items }) => <></>; // this line has the error
Generic type 'CompProps' requires 1 type argument(s).

意思是,我仍然必须在某个地方声明类型。这意味着我需要知道的变化GenericItem在使用该组件之前键入。

SpecificItem只是恰好与以下类型重叠的类型的表示GenericItem类型定义。

在大多数情况下,Comp不知道实际使用什么类型,并且 any 不会向作者提供任何有用的信息。

我希望有类似的事情...

type CompProps <T extends GenericItem> = {
    items: <T extends GenericItem>[];
    fn: <infer from T>[];
}

但我不确定这是否存在,或类似的东西。


:脸掌:

The CompProps using <T extends GenericType = any>是执行此操作的正确方法。

type CompProps <T extends GenericItem = any> = {
    items: T[];
    filter: (item: T) => boolean;
}
const Comp: React.FC<CompProps> = (props) => <></>;

魔法就在这里发生:

const App = () => {
    ...
    const filter = (item: SpecificItem) => item.someOtherProp;
    ...
}

The const Comp: React.FC<CompProps>不关心泛型类型是什么,因此= any。只要它至少具有相同的形状GenericType.

但里面App组件,我们在其中定义过滤器属性的方法,我们声明SpecificItem参数中的 typedef。仅有的that方法使用SpecificItem类型定义。CompProps只关心它是否符合所需的形状GenericItem.

希望对某人有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

组件 props 中的函数参数不兼容 的相关文章

  • React Context - Context.Consumer 与 Class.contextType

    我正在学习新引入的 React Context API 但我注意到它在示例中的消耗存在一些不一致 有的还是用原来的上下文 消费者HOC 方法 而有些 包括 React 文档 使用静态类 contextType method 有什么区别以及为
  • 如何在 Visual Studio 中调用“组织导入”TypeScript 功能?

    TypeScript 2 8 中有一个新功能 可以让您 组织进口 https devblogs microsoft com typescript announcing typescript 2 8 2 organize imports ht
  • 使用 Typescript 检查接口类型

    这个问题是直接类比使用 TypeScript 检查类类型 https stackoverflow com questions 12789231 class type check with typescript 我需要在运行时查明任何类型的变
  • TypeScript 类型别名循环引用自身

    使用 Typescript 3 6 3 我收到错误 Type alias JSONValue circularly references itself 我想知道如何删除这个特定版本的 TS 中的循环引用 因为更新版本中的相同代码按预期工作
  • Angular 4:类型“AbstractControl”上不存在属性“push”和“controls”

    我从这个链接实现了代码http plnkr co edit yV94ZjypwBgHAlb0RLK2 p preview http plnkr co edit yV94ZjypwBgHAlb0RLK2 p preview但获取推送和控制错误
  • 如何在 TypeScript 中导入 JavaScript 模块

    我有一些 JavaScript 代码正在尝试转换为 Typescript 据推测 TypeScript 是 JavaScript 的超集 但以下内容有编译器错误 假设我没有将 ko 库导入到 typescript 中 我将如何转换以下代码
  • 无法处理未捕获的类型错误:无法读取 createRouterReducer 处未定义的属性“位置”

    我在将路由器连接到 rootReducer 时遇到问题 控制台日志 未捕获的类型错误 无法读取未定义的属性 位置 在 createRouterReducer reducer js 005c 9 不知道如何修复它并将路由器连接到减速器 app
  • “React”在定义之前就被使用了

    我正在使用 create react app typescript eslint 应用程序 在构建过程中出现这样的错误 Line 1 8 React was used before it was defined typescript esl
  • 如何在打字稿中使用外部js

    我通过 Typescript 代码生成 Angular JS 代码 在一种情况下 我需要将外部 JS 文件添加到我的打字稿文件中 并且需要访问 js 文件中的类 我像这样添加js文件
  • 从 Flask 运行 NPM 构建

    我有一个 React 前端 我想在与我的 python 后端 API 相同的源上提供服务 我正在尝试使用 Flask 来实现此目的 但我遇到了 Flask 找不到我的静态文件的问题 我的前端构建是用生成的npm run build in s
  • 打字稿和布尔过滤器

    考虑以下code https www typescriptlang org play src var 20a 3A 20 number 20 7C 20null 5B 5D 20 3D 20 5B0 2C 201 2C 202 2C 203
  • VS Code 扩展 - 获取完整路径

    我正在为 VS Code 编写一个插件 我需要知道调用扩展的文件的路径 无论是从编辑器上下文菜单或资源管理器上下文菜单调用还是用户只需键入扩展命令 function activate context get full path of the
  • 使用 Typescript 时的 MongoDB FindOptions

    我正在将 JS 项目转换为 TS 并且在查询集合时遇到 FindOptions 问题 我只想获取集合中所有元素的 ID 这是导致 TS 错误的 TS 代码 import Collection Db Document MongoClient
  • 如何将yarn add/npm install与monorepos一起使用

    我需要从 GitHub 中的私有 monorepo 下载节点包 类似于 monorepoProject subProjectA subProjectB 还有两个子项目A and 子项目B是 typescript 项目 如下图所示 subPr
  • 打字总是抱怨全局模块

    我对打字稿很陌生 无论我尝试安装什么类型 我都会得到 打字错误 消息 尝试将 Angular 编译为外部模块 但它看起来像全局模块 我只是想做 typings install dt angular 我究竟做错了什么 Update 如果您对此
  • TypeScript - 如何从方法的参数推断类泛型类型?

    我正在尝试从稍后调用的方法参数中输入类泛型 在我们调用带有泛型参数的方法之前 类的泛型类型是不知道的 然后 对于任何其他方法 将传递泛型类型 老实说 对我来说 这似乎是一个非常复杂的功能 我什至不确定 TypeScript 是否有办法做到这
  • 是否应该使用箭头函数创建类方法

    在创建 React 组件时 我有时会在网络上使用箭头函数语法创建方法 有时则不使用箭头函数语法 例如 class Component extends someFnk param gt vs class Component extends s
  • Angular:扩展服务和传递参数

    我很难理解如何在 Angular 中扩展服务 我有一个连接到 Firebase 并执行各种常见任务 获取 设置 更新 列表等 的服务 我没有为我的特殊组件重写它 而是尝试扩展它 我的想法是我可以只传递路径的新部分 但这会引发错误 Canno
  • Karma + JSPM + Typescript - 未找到“.ts.js”

    主要只是想让 Karma JSPM 在加载 ts 文件时发挥良好作用 但绝对没有运气 我看到一个讨论库 https github com Larchy karma jspm typescript coverage tree master一个
  • 无法绑定到“属性 X”,因为它不是“子组件”的已知属性

    在我的项目中 我有一个通用类和一些从该类继承的其他组件 BaseRdnInput ts Injectable export abstract class BaseRdnInput implements ControlValueAccesso

随机推荐

  • 如何增加 google kubernetes 引擎上主节点的大小?

    我正在寻找一种增加 GKE 上主节点虚拟机大小的方法 On https kubernetes io docs admin cluster large size of master and master components https ku
  • 如何重新添加已删除的 VSTO 外接程序

    我在一台机器上遇到了一个关于 Word VSTO 加载项的奇怪问题 其中运行 Visual Studio 项目会打开 Word 但据我所知 不会尝试启动加载项 之所以出现这种情况 是因为我不小心在 管理 COM 加载项 页面上单击了加载项的
  • 进行搜索/将自定义结果加载到 ember 商店中?

    一直在搜索和阅读 ember data 的源代码 但我无法弄清楚如何做到这一点 所以我的索引页面加载数据如下 App SaleRecordsRoute Ember Route extend setupController function
  • 以编程方式刷新系统托盘图标

    我有一个带有系统托盘图标的应用程序 卸载时 如果进程正在运行 我将终止该进程 因此 由于我没有正常停止应用程序 该图标仍保留在系统托盘中 只有当我们将鼠标悬停在其上时才会删除 我编写了一个代码 可以沿着托盘运行光标并使光标返回到其初始位置
  • 将关联数组转换为具有关联子数组的索引数组

    我有一个带有国家 地区数据的简单关联数组 如下所示 array array country1 gt CountryOne country2 gt Country Two 我怎么能够动态地将此数组转换为多个数组 如下所示 array 2 0
  • 将 android 预览帧转换为 OpenCV Mat

    我正在尝试从相机预览中捕获图像并使用 OpenCV 将其转换为 Mat 对象 我注册了callbak方法public void onPreviewFrame byte data Camera camera 所以我从相机收到所有预览帧 但无法
  • 在laravel 4中的插入查询存储过程中传递参数

    我创建了一个插入过程 但不知道如何在控制器和模型中调用参数 名称 和 路径 存储过程 CREATE DEFINER root localhost PROCEDURE insert document details IN name VARCH
  • 在 Angular 2.0.0-beta.0 中,表单输入的 Observable 中缺少 map() 和 filter()

    在 Angular 2 0 0 alpha 47 中Observable从呼叫中返回formInput valueChanges 拥有所有高阶函数 即我可以做这样的事情 this search valueChanges debounceTi
  • 找不到“org.eclipse.persistence”Maven 依赖项

    我使用 m2eclipse maven 插件安装了 Eclipse Helios 我想使用 JPA 创建一个应用程序 所以 我所做的是 新建 gt Maven 项目 然后选择 Maven 默认原型 问题是我想添加我找不到的 org ecli
  • Java中synchronized关键字的记忆效应

    这个问题之前可能已经得到解答 但由于问题的复杂性 我需要确认 所以我重新表述这个问题 问题1 当线程进入同步块时 内存屏障将包括所触及的任何字段 而不仅仅是我同步的对象的字段 因此 如果在同步块内修改许多对象 则会在线程内存缓存之间进行大量
  • 如何通过Javascript更改CSS类样式?

    根据我正在阅读的书 当你使用Javascript时 最好按类更改CSS 但如何呢 有人可以为此提供一个示例片段吗 假设您有 div class oldclass text div 以及以下样式 oldclass color blue new
  • 是否有 VBA 代码来查看 Enterprise Project 2013 文件在打开之前是否已签出?

    试图帮助我们的 Project 2013 用户使用一些 VBA 代码 但我们似乎无法找到答案来查找是否使用 VBA 在我们的 PWA 服务器上检出 Project 2013 文件 它们基本上有一个项目列表 设置为单个项目文件中的任务 VBA
  • Android 定时器摆动

    我需要创建一个计时器来定期更新用户界面 但 Swing Timer 类在 Android 上不可用 我该如何解决这个问题 我会避免创建线程 然后使用 java util 包中的 Timer 类 你可以使用Handler http devel
  • 如何在 Mac OS X 上获取内存泄漏的行编号堆栈跟踪?

    我已经成功获得了 Xcodeleaks报告我的命令行 GCC Ada 程序中的泄漏的工具 通过添加delay 11 0 最后让leaks进行检查 然后 export MallocStackLogging 1 foobar leaks foo
  • 正则表达式中的[^.]*是什么意思?

    我试图从以下文本中获取 482 75 span 482 75 span 我使用的正则表达式是 regex span span 它起作用了 但我不明白的是为什么 可以在这里匹配 aapl 我的理解是 表示除换行符之外的任何字符 表示否定 因此
  • 如何在 ASP.NET Core MVC 上正确设置 cookie 的过期日期时间

    我正在尝试从后端 Asp Net core 向浏览器设置一个 Cookie 该 Cookie 应在第二天同一时间减去 5 分钟后过期 这是来自控制器的 C 代码 HttpContext Response Cookies Append MyC
  • Erlang - 随机数生成器

    我正在使用以下内容生成一个近乎随机的数字 3 gt erlang ref to list make ref Ref lt 0 0 0 36 gt 我想要的是00036 嗯 这就是我在上一篇文章中被告知我可以做的事情 我发现从 make re
  • 是否可以将数据导入Hive表而不复制数据

    我将日志文件以文本形式存储在 HDFS 中 当我将日志文件加载到 Hive 表中时 所有文件都会被复制 我可以避免所有文本数据存储两次吗 编辑 我通过以下命令加载它 LOAD DATA INPATH user logs mylogfile
  • 防止转换 HTML 实体时出现工具提示

  • 组件 props 中的函数参数不兼容

    我有一个组件 它接受一个项目列表 已知有一个 ID 以及一个过滤这些项目的函数 具有 ID 的类型是项目的通用类型 所有项目都将具有 但更具体的项目将包括其他道具 type GenericItem id string type Specif