Avoid angle-bracket type assertions (<Type>) and use 'as Type' syntax instead
The angle-bracket type assertion syntax (<Type>value) is deprecated in TypeScript, especially in TSX files where it conflicts with JSX syntax.
<Type> Syntaxas Typeas TypeDeprecated:
const value = <string>someValue;
const num = <number>input;
Modern:
const value = someValue as string;
const num = input as number;
Deprecated:
const user = <User>jsonData;
const config = <AppConfig>settings;
Modern:
const user = jsonData as User;
const config = settings as AppConfig;
Type assertions bypass type checking and should be avoided when possible.
Bad:
function processValue(value: unknown) {
const str = value as string;
return str.toUpperCase();
}
Good:
function processValue(value: unknown) {
if (typeof value === 'string') {
return value.toUpperCase();
}
throw new Error('Expected string');
}
Bad:
const user = apiResponse as User;
Good:
function isUser(value: unknown): value is User {
return (
typeof value === 'object' &&
value !== null &&
'id' in value &&
'name' in value &&
typeof value.id === 'number' &&
typeof value.name === 'string'
);
}
const parsed = apiResponse;
if (isUser(parsed)) {
const user = parsed;
} else {
throw new Error('Invalid user data');
}
Best:
import { z } from 'zod';
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string().email(),
});
type User = z.infer<typeof UserSchema>;
const user = UserSchema.parse(apiResponse);
Bad:
const element = document.getElementById('myId') as HTMLButtonElement;
Better:
const element = document.getElementById('myId');
if (element instanceof HTMLButtonElement) {
element.addEventListener('click', handler);
}
Or use querySelector with type inference:
const element = document.querySelector<HTMLButtonElement>('#myId');
if (element) {
element.addEventListener('click', handler);
}
Bad:
function handleEvent(event: Event) {
const mouseEvent = event as MouseEvent;
console.log(mouseEvent.clientX);
}
Good:
type AppEvent =
| { type: 'mouse'; clientX: number; clientY: number }
| { type: 'keyboard'; key: string }
| { type: 'custom'; data: unknown };
function handleEvent(event: AppEvent) {
switch (event.type) {
case 'mouse':
console.log(event.clientX);
break;
case 'keyboard':
console.log(event.key);
break;
case 'custom':
console.log(event.data);
break;
}
}
In TSX files, angle-bracket syntax causes syntax errors:
Will cause syntax error in TSX:
const Component = () => {
const value = <string>getData();
return <div>{value}</div>;
};
Must use as syntax:
const Component = () => {
const value = getData() as string;
return <div>{value}</div>;
};
Even better - validate properly:
const Component = () => {
const data = getData();
if (typeof data !== 'string') {
throw new Error('Expected string');
}
return <div>{data}</div>;
};
If you must use assertions (rare cases):
as const for Literal Typesconst config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
} as const;
as Type (Never <Type>)const value = unknownValue as SomeType;
const element = document.getElementById('app-root') as HTMLDivElement;
Find all angle-bracket assertions:
grep -r '<[A-Z][a-zA-Z]*>' --include="*.ts" --include="*.tsx"
Replace with as syntax:
<Type>value → value as TypeReview each assertion:
Enable linting:
{
"rules": {
"@typescript-eslint/consistent-type-assertions": [
"error",
{
"assertionStyle": "as",
"objectLiteralTypeAssertions": "never"
}
]
}
}
Enforce as syntax and discourage assertions:
{
"rules": {
"@typescript-eslint/consistent-type-assertions": [
"error",
{
"assertionStyle": "as",
"objectLiteralTypeAssertions": "never"
}
],
"@typescript-eslint/no-unnecessary-type-assertion": "error"
}
}
Never use angle-bracket syntax:
as Type when assertions are unavoidable