• Sound mode S-02, pre-alpha
  • Design record 0007, Accepted

TSR0201

Type assertion from '{0}' to '{1}' narrows the type. Use 'parse<{1}>', 'is<{1}>' or a narrowing check instead.

A type assertion ('as T' or '<T>x') narrows the type without a check. Use parse<T>, is<T> or a narrowing check instead.

Rule S-02: No narrowing type assertions (level: sound). Reported by ts-r-check and ts-r-lsp in files that opt in to sound mode. See Sound mode.

What it means

e as T and <T>e are allowed only when e is already assignable to T (an upcast). as const, satisfies T and assertions to unknown are always allowed. A source of type any counts as unknown, and in x as unknown as T the outer assertion is checked on its own. A cast of a value from an external source reports TSR1401 instead.

Example

Spec case from design record 0007 (checked by the record's case harness, not by this site's build)
// unknown to a type parameter.
function cast<T>(x: unknown): T {
  return x as T; // @expect TSR0201
}
export const s: string = cast<string>(1);

How to fix

  • Validate the value: parse<User>(data), or check it with is<User>(data).
  • Narrow with instanceof or a discriminant check (for DOM elements: if (el instanceof HTMLInputElement)).
  • For test fixtures written as {} as T, build a complete value with a typed builder.
  • If the code really is safe, use // @ts-r-unsafe S-02: <reason> on the line before.

Sound mode is defined in design record 0007 (accepted 2026-10-15).