Our types
enum TokenType {
VariableDeclaration = 'VariableDeclaration',
AssignmentOperator = 'AssignmentOperator',
Literal = 'Literal',
String = 'String',
LineBreak = 'LineBreak',
Log = 'Log'
}
interface TokenNode<T extends TokenType> {
type: T
}
interface TokenValueNode<T extends TokenType> extends TokenNode<T> {
value: string
}
type Token =
TokenNode<TokenType.AssignmentOperator> |
TokenNode<TokenType.VariableDeclaration> |
TokenNode<TokenType.LineBreak> |
TokenNode<TokenType.ConsoleLog> |
TokenValueNode<TokenType.Literal> |
TokenValueNode<TokenType.String>
Phew, some actual code.
Take a minute to read over this, and we'll step through it to explain what it's doing, and why we're doing it.