Coroutine tutorial example doesn't type check
When using Typescript (v4.8.2), the example from the second tutorial doesn't typecheck.
const {
letters,
coroutine,
char
} = require('arcsecond');
const fullParser = coroutine(function* () {
const firstWord = yield letters;
yield char(' ');
const secondWord = yield letters;
return {
type: 'word list',
words: [
firstWord.toUpperCase(),
secondWord.toUpperCase()
]
};
});
Object is possibly 'undefined'.
55 firstWord.toUpperCase(),
~~~~~~~~~
Object is possibly 'undefined'.
56 secondWord.toUpperCase()
~~~~~~~~~~
Hey @nvladimiroff,
This is a known issue that occurs because of limitations of typing for generators in TypeScript. Because the generator is actually used by the coroutine function in a specific way, there is a disconnect between the type system and the kind of DSL that has been built up. This wouldn't be as much of a problem if the generator was only ever expected to yield one type of parser result (string, number, whatever), but it's meant to be generic.
The work around is to use something like this, which I may add to the library directly in a next release:
import {letters, coroutine, char, Parser} from 'arcsecond';
const yieldTyped = <T>(yielded: any, _parser: Parser<T>) => yielded as unknown as T;
const fullParser = coroutine(function* () {
const firstWord = yieldTyped(yield letters, letters);
yield char(' ');
const secondWord = yieldTyped(yield letters, letters);
return {
type: 'word list',
words: [
firstWord.toUpperCase(),
secondWord.toUpperCase()
]
};
});
This is really just a comfortable forced-cast, and will not prevent you from specifying a different parser as the second argument. Not perfect, but can be useful if you're willing to accept a balance between type-safety and utility.
Gotcha, that makes sense.
Would an approach like what typed-redux-saga did work for arcsecond too? It looks like that tries to fix a similar problem for redux-saga. (but feel free to let me know if I'm wrong there!)
This has found a nice solution in the form of #90, and will be in the next major version.