【问题标题】:How to reuse a TypeScript union type from a 3rd party @types module?如何重用来自第 3 方 @types 模块的 TypeScript 联合类型?
【发布时间】:2020-07-23 02:00:36
【问题描述】:

所以我是 TypeScript 的新手,想知道是否有办法重用来自第 3 方 @types 模块的联合类型。

例如,在@types/node 中,我们有以下用于缓冲区编码的联合类型:

// Buffer class
type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";

如果我有一个实用函数将值传递给Buffer.from(),我需要指定一个与“BufferEncoding”类型兼容的联合类型,我不能像这样使用“string”:

export function convertToBuffer(input: string | Buffer, encoding?: string): Buffer {
    if (input instanceof Buffer) return input;
    return Buffer.from(input, encoding);
}

显然,我可以从 @types/node 复制并粘贴 BufferEncoding 类型,但这不会使我的代码保持干燥,并且不允许从 @types/* 模块导入。

export type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";

export function convertToBuffer(input: string | Buffer, encoding?: BufferEncoding): Buffer {
    if (input instanceof Buffer) return input;
    return Buffer.from(input, encoding);
}

我对使用“any”类型或其他放松类型检查严格性的方法不感兴趣。我怀疑我所问的可能是不可能的,这很好。

【问题讨论】:

  • 您不应该从@types/* 导入。只需使用BufferEncoding 而不导入 - 它应该在节点环境中可用
  • ** 安装一次@types/node
  • 所以这适用于 Node 类型,但我无法让它适用于其他类型的包,我收到错误 Cannot find name 'X'.ts(2304)。这可能是我做错了什么还是我正在使用的类型包有问题?
  • 您应该定期导入的其他包中的类型 import { Foo } from 'bar' 其中bar 是包的名称

标签: javascript node.js typescript types union-types


【解决方案1】:

非常感谢 Aleksey 为我指明了正确的方向。事实证明,我在这里遇到了几个不同的问题。

  1. Node 核心包的类型 - 确实就像运行 npm install --save @types/node 一样简单,然后无需导入任何内容即可使用 BufferEncoding 等类型。
export function doSomething(encoding?: BufferEncoding): void { ... }
  1. 解构嵌套对象 - 如果您使用解构或其他方式重新分配变量,TypeScript 编译器将无法推断变量的类型。

解构对象以提取我们需要的变量是一种常见的模式:

import errors from './errors';
const { http: { BadRequestError } } = errors;

export function doSomething(err: BadRequestError): void { ... }

但是,这会导致 TypeScript 编译器出现问题并给出如下错误:

  • 'BadRequestError' refers to a value, but is being used as a type here. ts(2749)
  • Parameter 'err' of exported function has or is using private name 'BadRequestError'. ts(4078)

解决办法是避免重新赋值,直接引用变量:

import errors from './errors';

export function doSomething(err: errors.http.BadRequestError): void { ... }

【讨论】:

    猜你喜欢
    • 2021-10-17
    • 2020-04-08
    • 1970-01-01
    • 2016-12-29
    • 2017-09-21
    • 2021-04-11
    • 2021-06-09
    • 1970-01-01
    • 2018-07-11
    相关资源
    最近更新 更多