Chevrotain / chevrotain

Parser Building Toolkit for JavaScript
https://chevrotain.io
Apache License 2.0
2.44k stars 199 forks source link

Improved type safety for token names #1987

Open LaurensRietveld opened 9 months ago

LaurensRietveld commented 9 months ago

Take this code block:

const Filter = createToken({
  name: "Filter" as const,
  pattern: new RegExp("filter", "i"),
}) 
const functionName = this.CONSUME(Filter);
return { type: functionName.tokenType.name };

Considering the name of the TokenType interface is always string, the return type of this function is {type: string}.

Where the above snippet is simple/small, this creates overhead for larger grammars where better type information is wanted, and adds the burden of specifying more accurate types to the developer. Ideally, the types are derived automatically, making the returntype of the MWE type: "Filter"

LaurensRietveld commented 9 months ago

I managed to work around this by overwriting the CONSUME function, and using my own createToken function. See here:

function createToken<N extends string>(config: Omit<ITokenConfig, "name"> & { name: N }) {
  return origCreateToken(config) as Omit<TokenType, "name"> & { name: N };
}
class ... {
  public CONSUME<S extends TokenType>(token:S) {
    return super.CONSUME(token) as Omit<IToken, "tokenType"> & {tokenType: S}
  }
}