Closed
Description
Before You File a Proposal Please Confirm You Have Done The Following...
- I have searched for related issues and found none that match my proposal.
- I have searched the current rule list and found no rules that match my proposal.
- I have read the FAQ and my problem is not listed.
My proposal is suitable for this project
- My proposal specifically checks TypeScript syntax, or it proposes a check that requires type information to be accurate.
- My proposal is not a "formatting rule"; meaning it does not just enforce how code is formatted (whitespace, brace placement, etc).
- I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).
Description
One of the hardest thing to explain to people not experienced in TS is when it's ok to use as
. I default to tell people "don't use as
", and I constantly have to deal with that in code reviews. I'd love to have a rule that only allows type assertions that widen a type. For example, as unknown
is always totally ok. as string | number
is safe on a string
, but unsafe in a string | boolean
.
This rule should only allow doing x as Type
in the cases where the type of x
is assignable to type
. So, the rule of thumb would be: if const a: Type = x
is fine, then x as Type
is fine. Otherwise it's not.
Fail Cases
const x = 'something';
const y = x as unknown as number; // Type `unknown` is not assignable to type `number` 🚫
//-----------
function f() {
return Math.random() < 0.5 ? 42 : 'meh';
}
const z = f() as number; // Type `number | string` is not assignable to type `number` 🚫
Pass Cases
const a = 'something';
const b = a as unknown; // Type `string` is assignable to type `unknown` ✅
//-----------
function g() {
return Math.random() < 0.5 ? 42 : 'meh';
}
const h = f() as number | string | boolean; // Type `number | string` is assignable to type `number | string | boolean` ✅
//-----------
const person = {
name: 'Chuck',
lastName: 'Norris' as string | undefined // Type `Norris` is assignable to type `string | undefined` ✅
}
person.lastName = undefined; // this is fine because of the type assertion (just showing why we'd want the `as string | undefined`)
Additional Info
Here's a link to a TS playground with the passing and (proposed) failing cases.