-
I just learned that #TypeScript can actually type narrow
Array.prototype.filtervia anisclause:const values = ['a', 'b', null, 'd']; const result = values.filter((v): v is string => !!v); // Inferred asstring[]!typescriptlang.org/play?#code/MYewdgzgLgBAbgQwDYFcCmEYF4YG0DkC+ANDPgEYkxgpJKn4Am+AugNwBQoksAThrVg5EqDADoAZgEskUNLwAUCuAEoAXPBhTM0XlLABzbAD4YAQjOq2QA -
What's extra cool is that this is *not* special-cased in the compiler. Apparently you can use
isin a type declaration to declare a new generic as part of the expression, here is the source forArray.prototype.filter: github.com/microsoft/TypeScript/blob/404a7d602df9c19d98d49e6a6bf2295e423be676/lib/lib.es5.d.ts#L1176 -
We can even do this generically to remove
nullfrom the input type, rather than restating a non-nullable version:const list = [1, 2, null, 3]; list.filter((v): v is NonNullable<typeof list[number]> => v !== null);typescriptlang.org/play?#code/PTAEBkHsDsHNQC4E8AOBTANKAJjA5AqAO4CG0hCkoATmuiYQJYIB0AUAMYwDOhANo14AuUAEFq1EkgA8vaozigAPqABGkSHzRlloaAFcAtqrTVdBvnwB8oALygA2gTS88WAExYE1fZj37LAF0AbjY2EFAAJTRDSAA3F1AAAws+JNAAM2pIQ0QACzRQBRR9ClRCsmwi6AzTblAuCTQOBD4kdi5oXhoXAMJ7AV4WDMY+BFMACgm4kj5fAEoRGbnCwVAAORh1gL4SVS1pZHRIDNBBhAcDY1NAm1sbZd9QAEJbe1T54KA -
Now if only we could somehow make:
(value: T) => !!valueinfer to(value: T): value is NonNullable<T> => !!valuewe'd be golden. Is there any reason the compiler can't do that? It already type narrows, we'd just need to plumb it through to the return type. -
I guess the tricky part here is probably remembering that it came from a function parameter and tying the return type to the narrowed form of that parameter. It also assumes that
valueis not modified, which may not always be true, but would probably break inference anyways.
develwoutacause’s Twitter Archive—№ 994