只能用花括号调用函数 exported/deconstructed 而不能用方括号

Can only call function exported/deconstructed with curly braces but not square brackets

在一个基本的 React 自定义钩子中,唯一的区别是返回 [ ]{ }:

const useCustomHookSquare= () => {
  const [state, setState] = useState<Type>(initialState);

  return [state, storeBounceBox];
}

const useCustomHookCurly= () => {
  const [state, setState] = useState<Type>(initialState);

  return {state, storeBounceBox};
}

这个有效:

const {state, setState} = useCustomHookCurly();
// or even
const {setState} = useCustomHookCurly();

但是在调用 setState 函数(或以这种方式导出的任何其他函数)时,用方括号进行解构会给我一个 TypeScript 错误:

const [state, setState] = useCustomHookSquare();
setState(someState); // "This expression is not callable. Type has no call signatures".

我觉得这里缺少一些基本的 JavaScript 概念。为什么 {} 版本允许我调用函数但 [] 版本不允许?

因为您的 useCustomHookSquare 钩子没有 return 类型信息,TypeScript 推断它 return 是一个包含两种不同类型的数组。但并非可以成为该数组一部分的两种类型都是函数,因此您会收到类型错误,因为其中一个可能的值不可调用。

const useHook = () => {
  return ["item", () => true]
}

// The inferred value of useHook is now
//
// (string | (() => boolean))[]
//
// So when calling `fn`, TypeScript doesn't know if it will be a string or a function
const [item, fn] = useHook()

//This expression is not callable.
//  Not all constituents of type 'string | (() => boolean)' are callable.
//    Type 'string' has no call signatures.
fn()

向您的 useCustomHookSquare 函数添加一些 return 类型以解决问题。这是我的固定示例的样子。

const useHook = (): [string, () => true] => {
  return ["item", () => true]
}

TypeScript 现在可以理解 returned 数组中只有 2 个项目,并且这些项目类型应该始终相同。

默认情况下,typescript 会为数组分配更宽的类型。所以如果你有:

const arr = ["str", 5];

类型将是 (string | number)[] 的数组,而不是 [string, number] 的元组。

要使其成为元组,请使用 as const:

const useCustomHookSquare= () => {
  const [state, setState] = React.useState<string>();

  return [state, setState] as const;
}