在打字稿中向类添加静态类型

问题描述 投票:0回答:1

我在 TypeScript 中有以下设置:

// complex.ts
export type ComplexInput = { real: number, imag: number }

export class Complex {
  constructor(value: ComplexInput) {
    // …
  }
}
// index.ts
import { Complex, type ComplexInput } from './complex.ts'

const input: ComplexInput = {
  real: 3,
  imag: -2,
}

const complex = new Complex(input)

这工作得很好,但我想在类中定义

ComplexInput
类型,以便它的范围仅限于类,并且可以像 Complex.Input
 一样被引用。理想情况下,我希望实现这样的目标:

// complex.ts export class Complex { type Input = { real: number, imag: number } // Hypothetical syntax constructor(value: Complex.Input) { // … } }
// index.ts
import { Complex } from './complex.ts'

const input: Complex.Input = {
  real: 3,
  imag: -2,
}

const complex = new Complex(input)
由于 

type

 声明不允许直接在类内部进行,那么如何在保持类型定义与类紧密关联的同时实现此行为?是否有推荐的方法将此类类型封装在 TypeScript 的类中?

typescript typing
1个回答
0
投票
允许在

type

 中使用 
class
 别名是 TypeScript 缺少的功能,请在 
microsoft/TypeScript#7061 请求。直到并且除非它被实现(虽然它有几百个赞成票,但我没有看到任何迹象表明它会实现),你可以通过声明合并来解决它。 如果您希望 Complex.Input
 成为一种类型,则可以有效地将 
Complex
 用作 
namespace
。所以你可以这样声明它,TypeScript 会自动合并它们:

export declare namespace Complex { export type Input = { real: number, imag: number } } export class Complex { constructor(value: Complex.Input) { // … } }
TypeScript 团队开发负责人在 microsoft/TypeScript#7061

中提到此解决方法,称其既不是“非常好”也不是“可怕”。这样做似乎并不常见,但这也不是坏习惯。 我无法真正权威地谈论你是否应该关心像

@typescript-eslint/no-namespace

这样的linter规则,因为它是主观的。  在我看来,反对 
namespace 的论点是它是
JavaScipt 模块
的较旧替代品。但是 declare namespace Complex 不会创建任何运行时代码;它与类型系统的其余部分一起被完全“擦除”......所以它不一定是违规的。运行时不存在我们鼓励您用 JavaScript 模块替换的“TypeScript 内部模块”。 您可能需要启用
allowDeclarations 选项,以便仅在使用 namespace
 生成运行时代码时才标记它们。但同样,这部分是意见,其他人可能会不同意,但没有人“客观”正确。
Playground 代码链接

© www.soinside.com 2019 - 2024. All rights reserved.