TypeScript 在将函数导入另一个文件后更改函数的类型定义
TypeScript changing type definition of a function after importing it to another file
我有一个名为 useDropdownSelection
的自定义挂钩。这很简单。这是代码:
import { useState } from 'react'
export const useDropdownSelection = (initialValue: string) => {
const [selectedOption, setSelectedOption] = useState<string>(initialValue)
const handleClick = (event: React.MouseEvent<HTMLLIElement>) => {
const target = event.target as HTMLElement
setSelectedOption(target.innerText)
}
return [selectedOption, handleClick]
}
如你所见,handleClick
函数的类型是(event: React.MouseEvent<HTMLLIElement>) => void
但是当我将它导入我的 index.tsx 时,handleClick
函数由于某种原因变成了 string | ((event: MouseEvent<HTMLLIElement, MouseEvent>) => void)
类型
const [selectedDropdownOption, handleDropdownClick] = useDropdownSelection('Most upvotes') // const handleDropdownClick: string | ((event: MouseEvent<HTMLLIElement, MouseEvent>) => void). WHY?
为什么会这样?
我认为这与我返回数组有关?
If you are returning an array in your Custom Hook, you will want to avoid type inference as TypeScript will infer a union type (when you actually want different types in each position of the array).
如果你想避免联合类型,你需要做的是使用 const 断言:
return [selectedOption, handleClick] as const;
现在 selectedOption 和 handleClick 将分别保留它们的类型。
文档:https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/hooks/#custom-hooks
因为你没有指定useDropdownSelection
每个索引要return特定类型的数组,所以TS假设每个索引可能包含回调和字符串值。
检查下面的例子:
const f = (s: string) => {
const n: number = 5;
return [s, n];
}
const result = f('s');
result
是 (string | number)[]
类型。要明确通知它将成为 [string, number] 你必须像下面这样实现它:
const f = (s: string): [string, number] => {
const n: number = 5;
return [s, n];
}
const result = f('s'); // type is [string, number]
上面提供的语法类似于 useState 实现的语法。
因此在您的示例中明确键入 return 钩子的值:
export const useDropdownSelection = (initialValue: string): [string, (event: MouseEvent<HTMLLIElement, MouseEvent>) => void] => {...}
我有一个名为 useDropdownSelection
的自定义挂钩。这很简单。这是代码:
import { useState } from 'react'
export const useDropdownSelection = (initialValue: string) => {
const [selectedOption, setSelectedOption] = useState<string>(initialValue)
const handleClick = (event: React.MouseEvent<HTMLLIElement>) => {
const target = event.target as HTMLElement
setSelectedOption(target.innerText)
}
return [selectedOption, handleClick]
}
如你所见,handleClick
函数的类型是(event: React.MouseEvent<HTMLLIElement>) => void
但是当我将它导入我的 index.tsx 时,handleClick
函数由于某种原因变成了 string | ((event: MouseEvent<HTMLLIElement, MouseEvent>) => void)
const [selectedDropdownOption, handleDropdownClick] = useDropdownSelection('Most upvotes') // const handleDropdownClick: string | ((event: MouseEvent<HTMLLIElement, MouseEvent>) => void). WHY?
为什么会这样?
我认为这与我返回数组有关?
If you are returning an array in your Custom Hook, you will want to avoid type inference as TypeScript will infer a union type (when you actually want different types in each position of the array).
如果你想避免联合类型,你需要做的是使用 const 断言:
return [selectedOption, handleClick] as const;
现在 selectedOption 和 handleClick 将分别保留它们的类型。
文档:https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/hooks/#custom-hooks
因为你没有指定useDropdownSelection
每个索引要return特定类型的数组,所以TS假设每个索引可能包含回调和字符串值。
检查下面的例子:
const f = (s: string) => {
const n: number = 5;
return [s, n];
}
const result = f('s');
result
是 (string | number)[]
类型。要明确通知它将成为 [string, number] 你必须像下面这样实现它:
const f = (s: string): [string, number] => {
const n: number = 5;
return [s, n];
}
const result = f('s'); // type is [string, number]
上面提供的语法类似于 useState 实现的语法。
因此在您的示例中明确键入 return 钩子的值:
export const useDropdownSelection = (initialValue: string): [string, (event: MouseEvent<HTMLLIElement, MouseEvent>) => void] => {...}