【问题标题】:TypeScript: Typing array / tuple with values or emptyTypeScript:用值或空输入数组/元组
【发布时间】:2021-03-20 02:51:24
【问题描述】:

我正在尝试输入一个自定义的 React 钩子:

import { useRef } from 'react';

type Reference = [
  Promise<unknown>,
  (value?: unknown) => void,
  (reason?: unknown) => void,
];

const usePromise = () => {
  const reference: Reference = [];
  const container = useRef(reference);

  reference[0] = new Promise((resolve, reject) => {
    reference[1] = resolve;
    reference[2] = reject;
  });

  // [promise, resolve, reject]
  return container.current;
};

export default usePromise;

TypeScript 抱怨 reference 说:

Type '[]' is not assignable to type 'Reference'.
  Source has 0 element(s) but target requires 3.

我怎样才能让 TypeScript 也接受空数组/元组初始化?而且也许还有一种方法可以给usePromise 值的类型,所以它不会说unknown

【问题讨论】:

    标签: arrays reactjs typescript react-hooks typescript-typings


    【解决方案1】:

    编辑 2:

    如果要将元组初始化为空数组,可以这样做:

    const reference : [Reference, Reference, Reference] = ([] as unknown) as [Reference, Reference, Reference];
    

    编辑:根据 OP 的评论进行编辑

    如果你想使用元组,你需要这样做: 请阅读下面的内联 cmets。

    type Reference = {
        name:  string;
        age: number;
    }
    
    //In your case, it should be something like this beause your tuple may have upto 3 values of type Reference.
    
    //initialization
    //null! - the '!' mark after null is the non-null assertion operator, which will let you assign null value to a type Reference.
    const reference2: [Reference, Reference, Reference] = [null!, null!, null!];
    //assignment
    reference2[0] = {name: 'John', age:10};
    

    原答案: 这是因为你声明了一个常量变量reference,它的类型为Reference(类、类型或接口的对象实例,称为Reference),但使用空数组[ ]对其进行初始化。

    如果您希望 reference 有一个 Reference 对象数组,那么您应该这样做:

    const reference: Reference[] = []; 
    

    如果您在 tsconfig 中启用了严格的类型检查,您应该这样做:

    const reference: Reference[] = [] as Reference[];
    

    您可以在此处阅读有关 as 关键字的信息:Stack Overflow question about the 'as' keyword

    【讨论】:

    • 谢谢链接!它不是References 的数组。它要么是一个包含 3 个值的元组(三元组),要么是一个空数组。如果我这样投射:[] as Reference,我会收到错误Conversion of type '[]' to type 'Reference' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. Source has 0 element(s) but target requires 3.。知道如何解决这个问题吗?
    • 所以const reference = ([] as unknown) as Reference; 工作了。不过,我不知道这是否是处理此问题的最佳方法。
    • 我已经更新了我的答案,请您尝试我建议的解决方案。如果它不会给您带来错误,请在不使用as Reference 的情况下尝试它。
    • 谢谢链接。不幸的是,您建议的类型不适用于我的实例。 (不是三个引用的数组,引用类型是三个值的元组或空数组。
    • 是的,在我上面的回答中,我正在创建一个包含 3 个引用类型值的元组。而且,为了将该元组的值分配给一个空数组,您需要这样做:const reference : [Reference, Reference, Reference] = ([] as unknown) as [Reference, Reference, Reference]
    【解决方案2】:

    Reference 类型是一个包含三个条目的元组。因此,当您分配给Reference 类型的变量时,打字稿会检查 1) 分配的值是否是元组 2) 分配的元组是否具有所需的长度 3) 元组中的所有条目类型是否与相应的类型匹配在Reference 类型中。

    您分配了一个空列表,这违反了这些条件。如果你没有启用严格的空检查,你可以简单地分配const reference: Reference = [null, null, null];

    【讨论】:

      【解决方案3】:

      我觉得最好将 reference 描述为真正的问题,而不是强制 typescript 忽略您的问题:

      let reference: Reference|null = null;
      

      或者:

      type Reference = [
        Promise<unknown> | null,
        ((value?: unknown) => void) | null,
        ((reason?: unknown) => void) | null,
      ];
      

      【讨论】:

      • 这会引发与我的问题相同的错误。
      猜你喜欢
      • 2021-08-03
      • 2020-06-03
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 1970-01-01
      • 2015-04-12
      • 2017-08-24
      相关资源
      最近更新 更多