The following TypeScript features can not be erased by ts-blank-space
because they have runtime semantics
enum
(unlessdeclare enum
) more detailsnamespace
(unlessdeclare namespace
)module
(unlessdeclare module
)import lib = ...
,export = ...
(TypeScript style CommonJS)constructor(public x) {}
more details
enum Direction {
North,
South,
East,
West,
}
Alternative approach to defining an enum like value and type, which is ts-blank-space
compatible:
const Direction = {
North: 1,
South: 2,
East: 3,
West: 4,
} as const;
type Direction = (typeof Direction)[keyof typeof Direction];
// ^? = 1 | 2 | 3 | 4
class Person {
constructor(public name: string) {}
}
Alternative ts-blank-space
compatible approach:
class Person {
public name;
constructor(name: string) {
this.name = name;
}
}
TypeScript type assertions have no runtime semantics, however ts-blank-space
does not erase the legacy prefix-style type assertions.
const x = <const>{ a: 1 };
// ^^^^^^^ not erased by `ts-blank-space`
In 2015 TypeScript 1.6 added an alternative style, which ts-blank-space
does support. The above can be re-written as:
const x = { a: 1 } as const;
Which ts-blank-space
will transform to:
const x = { a: 1 } ;
The as
style also has the advantage of not conflicting with JSX syntax.
The reason ts-blank-space
doesn't support the prefix style is because there are situations where erasing it would change the runtime semantics of the remaining JavaScript.
function foo() {
return <const>
[];
}
Erasing the type assertion would result in the following incorrect output:
function foo() {
return
[];
}
Because of the new-line after return
the above function is actually the same as:
function foo() {
return;
}
One possible approach ts-blank-space
could take to retain the original semantics is to insert some JavaScript:
function foo() {
return 0,
[];
}
However there are other places where prefix-style type-assertions can't be erased:
const fn = () => <const>{};
Erasing the type assertion would result in the following incorrect output:
const fn = () => {};
The above function is the same as:
const fn = () => {
return;
};
The comma-operator approach above doesn't work here because the comma (,
) could represent the end of the expression:
function foo(arg1 = () => 1, arg2 = 2) {
// ^ comma marks the end of the first argument
}
An alternative way for ts-blank-space
to fix up the output by adding JavaScript could be:
const fn = () => 0||{};
But this doesn't work for the following input:
const fn = () => <const>{ p: a }.p ?? b;
Because the following output is a syntax error:
const fn = () => 0||{ p: a }.p ?? b;
Due to the following:
- There does not appear to be a universal strategy for erasing prefix type assertions
- Potential solutions involve injecting JavaScript not present in the input
- Adding parenthesis
(
)
to the output requires generating a sourcemap <const>val
can be re-written toval as const
ts-blank-space
has decided to not support the prefix style.