javascript - 如何键入在 JS 中创建并在 TSX 文件中使用的自定义 React 挂钩?
问题描述
我有一个自定义钩子,不幸的是,它是用纯 JS 编写的,我在 TypeScript .tsx 文件中使用它。
我这样称呼它
const [toggleDictation, dictationResults] = useDictation()
useEffect(() => {
//start recognizing
toggleDictation();
}, []);
我在编译器中收到一条错误消息:
This expression is not callable.
Not all constituents of type 'string | boolean | never[] | (() => Promise<void>)' are callable.
Type 'string' has no call signatures.ts(2349)
自定义 JS 挂钩中的 toggleDictation 函数写为:
const toggleDictation = async () => {
try {
if (!speechHasStarted) {
await _startRecognizing();
return;
} else {
await _stopRecognizing();
return;
}
} catch (e) {
//eslint-disable-next-line
console.error("Error in toggleDictation, ", e);
return;
}
};
有没有办法进行类型转换或断言以正确设置函数类型以消除错误?
解决方案
这里真正的问题在于useDictation
函数。默认情况下,即使在打字稿中,返回数组的函数也是数组而不是元组类型。
const toggleDictation = async () => { }
const useDictation = () => { // returns Array<(() => Promise<void>) | never[]>
return [toggleDictation, []]
}
const [tg, arr] = useDictation(); // tg is (() => Promise<void>) | never[] so uncallable
在 ts 中,您可以添加一个as const
或显式类型注释来解决此问题:
const toggleDictation = async () => { }
const useDictation = () => { // returns Array<(() => Promise<void>) | never[]>
return [toggleDictation, []] as const
}
const [tg, arr] = useDictation(); // tg is now () => Promise<void>
tg() // ok
对于 JS 我们有一些选择,如果你控制了 js,你可以添加 jsdoc 类型,它们将被 TS 拾取:
const toggleDictation = async () => { }
/**
* @returns {[()=> Promise<void>, string[])]}
*/
const useDictation = () => {
return [toggleDictation, []]
}
let [tg, d] = useDictation(); // tg is ()=> Promise<void>
tg() // ok in ts as well
或者您可以添加一个声明文件,但这实际上取决于您的设置。如果您为模块创建声明,您将不再从 js 中获得任何推断。您可以d.ts
从 js 文件(自 3.7 PR起可用)生成 a 并更正任何声明(例如 的返回类型useDictation
)
declare const useDictation : () => [()=> Promise<void>, string[]]
let [tg, d] = useDictation(); // tg is ()=> Promise<void>
tg() // ok
推荐阅读
- artificial-intelligence - 如何区分从左到右和从右到左的 alpha-beta 修剪?
- angular - 在 Angular 9 中使用查询参数导航到 url
- haskell - 为什么这个的第二个版本在指数时间内运行?
- android - 导航组件可以在活动之间使用吗?
- typescript - Typescript 解构对象和对象的内部属性
- sql - Power BI 中没有周六和周日的上一个日期
- r - 如何在使用 pivot_wider() 后保留原始变量,而无需手动创建临时变量来传播数据?
- java - 如何验证从 yaml 文件开始的输入字段
- amazon-web-services - 应该用作 Runner Manager 并生成新机器的 EC2 实例正在运行管道作业
- node.js - 无法连接到 node.js API、EC2 AWS [已解决]