首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为所有3种可能的参数定义创建类型,并调用需要其中任何一种的函数

如何为所有3种可能的参数定义创建类型,并调用需要其中任何一种的函数
EN

Stack Overflow用户
提问于 2020-09-27 06:01:37
回答 1查看 57关注 0票数 1

(类型来自@type/markdown-it) https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/markdown-it/lib/index.d.ts#L93

我想为markdown-it use方法的可能参数创建参数类型,该方法的类型如下:

代码语言:javascript
复制
type PluginSimple = (md: MarkdownIt) => void;
type PluginWithOptions<T = any> = (md: MarkdownIt, options?: T) => void;
type PluginWithParams = (md: MarkdownIt, ...params: any[]) => void;

我有一个react钩子,我想像这样交上markdown-it插件:

代码语言:javascript
复制
type Plugin = MarkdownIt.PluginSimple |
  [MarkdownIt.PluginWithOptions, {}?] | 
  [MarkdownIt.PLuginWithParams, ...any[]]
type Plugins = Plugin[]

function useMarkdown(source: any, plugins?: Plugins) {
  React.useEffect(() => {
    plugins?.forEach(plugin => md.use(...plugin))
  }, [md, plugins])
}

首先,我不知道如何将模板参数添加到第二个插件定义中。

这不起作用:

代码语言:javascript
复制
[<T = any>MarkdownIt.PluginWithOptions<T>, T?]

但最重要的是,我希望TS编译器认识到使用md.use(...plugin)是安全的。它抱怨说,这个论点需要支持

Expected at least 1 argument, but git 0 or more An argument for 'plugin' was not provided. Type插件must have a '[Symbol.iterator]()' method that returns an interator

将我的代码行改为手动处理数组的情况:

代码语言:javascript
复制
plugins?.forEach(plugin => Array.isArray(plugin) ? md.use(...plugin) : md.use(plugin))

删除迭代器错误消息,但也保留另一条消息供...plugin使用

EN

回答 1

Stack Overflow用户

发布于 2020-10-25 11:14:12

您使用扩展语法将这三种情况都传递给了md.use,因此它们都必须是元组。对于PluginSimple,参数是长度为1的元组。

代码语言:javascript
复制
type Plugin = [PluginSimple] |
  [PluginWithOptions, any] | 
  [PluginWithParams, ...any[]]
type Plugins = Plugin[]

现在,对于需要1个或更多参数的错误,我们可以通过分别解构元组中的第一个条目和其他条目来确保typescript知道始终至少有一个参数。基于我们的联合类型,我们知道main总是被定义的,并且是插件类型之一,而rest是any[],对于简单插件来说将是[]

代码语言:javascript
复制
function useMarkdown(source: any, plugins: Plugins = []) {
  React.useEffect(() => {
    plugins.forEach(plugin => {
      const [main, ...rest] = plugin; 
      md.use(main, ...rest)
    })
  }, [md, plugins])
}

这并不完美,因为我们没有强制在PluginWithOptions和它的特定选项类型之间进行匹配,但希望它足以满足您的用例。对于更高级的类型,我会考虑定义自己的插件对象,它包含一个插件及其参数,而不是使用元组。

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

https://stackoverflow.com/questions/64082898

复制
相关文章

相似问题

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