Add transpileDeclaration API method by weswigham · Pull Request #58261 · microsoft/TypeScript (original) (raw)

Eh, it's weirder that we can't typecheck unique symbol literals/calls without the skeleton of the global Symbol definitions present (since it's not like symbol types are ES6+ specific). That's probably the real underlying issue that needs fixing - we really aughta bake their presence into the checker like undefined if they're so central to checking a basic type-syntax construct. Though, there's probably some other annoying things, too, though - like I don't think we'll emit Omit types for generic spreads without the global Omit type present, which even this is currently missing. Eg,

export function f<T extends {x: number, y: number}>(x: T) { const {x: num, ...rest} = x; return rest; }

has an inferred return type of Omit<T, "x">, but without Omit in the lib, it's just any (the error kind). There are a lot of "builtins" like this, whose fallback behavior when they aren't present isn't particularly good.

Personally, by default I think I'd rather load the fully correct lib for the options passed in, at least for transpileDeclaration, just because I think emitting export const a: any for export const a = Math.random() feels bad (even if it is an error under ID), but I don't know if that runs counter to the perf goals of the API (even if every invocation with the same lib could share cached lib AST copies). Still, I guess it comes down to a question of scope - loading a real lib to get the builtins to work is easy, but should you need to do that for isolatedDeclarations-compatible input? I appended this barebones lib to the input because I assumed at least unique symbol-related inferences are planned to work, and this is the minimal lib (well, OK, I could omit the empty Array interfaces and the like) to get that.

We could leave it up to the caller - and load the default lib for the options provided unless an override (like this minimal one or a completely empty/missing one) is passed in, or load no lib at all by default unless one is passed in as a transpile option. It's really a question of the intended usage, I suppose.