首页 > 解决方案 > 打字稿如何为界面混合动态([key:type]:type)和静态类型

问题描述

主要问题

不太确定这是否可能,但由于我讨厌 Typescript,而且它使我的编码变得困难,我想我会问只是为了确定。

interface ISomeInterface {
  handler: () => {}
  [key: string]: string
}

问题显然是,handler是 a() => {}而不是字符串,所以打字稿会引发错误。有可能以某种方式完成这项工作吗?

附录:

在这个主题上,假设这个接口被 a 使用,React.Context并且由于需要一个默认值 by React.createContext(/* requires default here */),我需要给它一个与该接口匹配的对象。当我尝试像这样传递一个对象时:

React.createContext({handler: () => {throw new Error('using default context')}})

Typescript 通过说{handler: () => never} cannot be assigned to {handler: () => {}}任何使这个界面合理的方法来制造骚动?我试图使接口实现() => any,仍然没有工作,它想要显式never

编辑#1:

所以我做了一些改变,即:

interface IFormContext {
  $handleChange: (key?, val?) => void
  $registerField: (key?) => void
  [key: string]: { value: string } | ((key?, val?) => void)
}

但是现在当我尝试访问这样的字段时:const {[key]: { value }} = props这基本上是使用动态键进行解构,我收到以下错误:

Property 'value' does not exist on type '{ value: string; } | ((key?: any, val?: any) => void)'.ts(2339)

标签: reactjstypescriptinterface

解决方案


不幸的是,您的命名属性必须与索引签名匹配。在这种情况下,由于至少有一个属性是函数,您可以使用:

[key: string]: string | Function;

或者

[key: string]: any;

两者都应该工作。

对于您的附录,() => {}意味着一个没有参数的函数返回一个空对象,而该函数() => {throw new Error('using default context')}不返回任何内容,因此是错误。类型和实际函数实现中使用的大括号有点混淆。

具有类型的函数() => {}实际上类似于() => {return {}}or () => ({})

对于不返回任何内容的函数,您可以使用nevervoid,但如果您的处理程序可能返回某些内容,您可以使用类似的东西handler: () => void | boolean,将 boolean 替换为它可能返回的类型。


推荐阅读