typescript - 有没有办法强制一个类包含一个特定的枚举值(最好是内联的)?
问题描述
我目前正在使用 TypeScript 中的编译器,并且我有一个 Enum 来表示令牌类型和一个用于实际令牌的类:
enum TokenType {
String,
Integer,
Float,
Identifier,
// ... elided
}
class Token {
type: TokenType
lexeme: string
lineNo: number
columnNo: number
constructor(
type: TokenType,
lexeme: string,
lineNo: number,
columnNo: number
) {
this.type = type
this.lexeme = lexeme
this.lineNo = lineNo
this.columnNo = columnNo
}
toString(): string {
return (
'Token{' +
[this.type, this.lexeme, this.lineNo, this.columnNo].join(',') +
'}'
)
}
}
在我的 AST 节点类型中,我想指定 Token 持有特定类型,例如在FunctionDeclaration
类型中:
type FunctionDeclaration = {
ident: Token with type = TokenType.identifier
// ^ Imaginary syntax, but this is what I'm trying to do
}
我试过使用extend
像:
interface IdentifierToken extends Token {
type: TokenType.Identifier
}
但是,即使令牌的类型new Token(TokenType.Identifier, ...)
是.IdentifierToken
TokenType.Identifier
此外,我宁愿不必为所有不同的 TokenTypes 声明新的单独类型(因为有 ~25 个)。那么,强制类属性值的内联方式是否可行?
解决方案
您可能需要考虑使用与您正在使用的特定子类型相对应的类型参数创建Token
一个泛型类:TokenType
class Token<T extends TokenType = TokenType> {
type: T
lexeme: string
lineNo: number
columnNo: number
constructor(
type: T,
lexeme: string,
lineNo: number,
columnNo: number
) {
this.type = type
this.lexeme = lexeme
this.lineNo = lineNo
this.columnNo = columnNo
}
}
然后你可以很容易地引用“ Token
atype
等于XXX
as Token<XXX>
:
type FunctionDeclaration = {
ident: Token<TokenType.Identifier>
}
此外,当您使用Token
构造函数时,编译器将T
根据构造参数进行推断:
const identifierToken = new Token(TokenType.Identifier, "", 1, 2);
// const identifierToken: Token<TokenType.Identifier>
const f: FunctionDeclaration = { ident: identifierToken }; // okay
const floatToken = new Token(TokenType.Float, "", 3, 4);
// const floatToken: Token<TokenType.Float>
const g: FunctionDeclaration = { ident: floatToken }; // error!
// Type 'Token<TokenType.Float>' is not assignable to type 'Token<TokenType.Identifier>'.
推荐阅读
- javascript - django api无法正常工作
- linux - 在文件中插入行号
- libreoffice-calc - 双向 ANCOVA:LibreOffice Calc 中的协方差分析
- rest - 通过 Kirby CMS REST API 使用响应式图像
- r - 驱动二进制版本“赶上”r 包的源版本有多快的影响是什么?
- php - Laravel 6 即使在注销后也可以执行用户限制的操作
- c# - Winforms对话框标题缩进没有图标
- mysql - MySQL 按计数排序而不对结果进行分组
- apache-flink - Flink DataStream 有类似 mapPartition 的 api 吗?
- c - 程序集别名和符号