Repository: TypeScript
Issue: Detect "partial aliased conditions" where string typeof is stored in a const, instead of boolean typeof === expression
Labels: Suggestion,Awaiting More Feedback

# Suggestion

## 🔍 Search Terms

aliased conditional expressions, aliased condition, const typeof value, control flow analysis, type narrowing, type guards

## ✅ Viability Checklist

My suggestion meets these guidelines:

* [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
* [ ] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).


## ⭐ Suggestion

TS 4.4 added ["Control Flow Analysis of Aliased Conditions"](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-4.html#control-flow-analysis-of-aliased-conditions-and-discriminants), which detects boolean consts that when used in conditionals should narrow the type.  The suggestion here is to also detect & narrow the type when _other_ consts (the string value of `typeof`) are incorporated _inside_ boolean expressions (`===`) in a conditional.

## 📃 Motivating Example

([Playground](https://www.typescriptlang.org/play?#code/PTAEHUHsCcGsGdQFpQHICG0DmrQEtEA7TaSAdwFMATUAF0joE8AHCteW6PQnAKADMAroQDGtPJEKgKAD3QBbZgBsKARgD63Jd2oBhABYURsABSYsALlDDYhcoQCUoAN69Q7-P1AnaLCpC9zUABeUNAAIg4uHnCnVw8E0BFJeEgVADolSCwzbHT6AFVmVmhddHgKEwcHAG43DwBfXibeEAgYBGQ0c1wCUGJoUkoaeiZWdk5uPiFRcUlpOUUVACZ1dG1yvUNjXMtrQlt7OPr3ZMIOfHgAZUmeELH-QOwQsMjbrHC6hLwvEwIb6JYY6JDxnVIZLI5cz5SBFEplCpVWonUBNFptACiACUsQB5LFdDDYXDQCjydDcRC+caoGx2MiEVACYRiCRSWQKZQUADMaw2FSoABU-LsrHSji4UWDaHR7tTHqBzF8PD9vDLQsEIlEprFJSDTik0hRMtldjC4RRSpskcr3GjeEA))

```ts
// Works - 'arg' is narrowed to type 'string'
function example2_aliasedCheck(arg: unknown) {
    const isString = typeof arg === "string";
    if (isString) {
        console.log(arg.toUpperCase());
    }
}

// ERROR - 'arg' remains type 'unknown'
function example3_aliasedType(arg: unknown) {
    const t = typeof arg;
    if (t === "string") {
        console.log(arg.toUpperCase());  // <-- ERROR
    }
}
```

Interestingly, it seems like this pattern is already supported for discriminated type unions – in the TS 4.4 release notes above, see the example that reads "Analysis on discriminants in 4.4 also goes a little bit deeper."

This suggestion might potentially apply to other kinds of value-driven type narrowing as well, e.g. truthy checks that act as non-nullable type guards – though that [appears to not work yet even with directly inlined checks](https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgGIHt0DkCuAbPOAIzxQG9koI4ATdEPAT2QA8AuZAZzClAHNkAH2Q4QNCDFAQaAbmQBfAFCLQkWIhQZ0AZR7AEYZBSq16TVh268QfOUuUxRB4PWQQWcALYAHUgAoYDi1cAmJSAEojRWQY5GAYZACAOhZIsmjYzIR6TnRSJLx0PmSWJLB0AFVvb2gAYThOCD9w8LlkAHp25AALaBQYFLjOZABrEHQAdxBkcuQiFHGQAFoQfEISFD8wRhqh5AByK3598IzMmNzPCAqwYDxgbYBZCDBu9BoA1pjO5ABRACV-gB5f4cXpUZAJYDDcaGMaTaazTxwMAIbpoTC6XgGZDiTjeB4oCbdFHICYLSajcYTZDEdA4QwDFhnBSKewOJy3VyXa63e5PF5vD6BDE6PQGNIs7IgXL5QrFJllSrVOoNJotGRsoA), so it probably shouldn't be in scope for this suggestion.

## 💻 Use Cases

The specific example where I saw this was code that 'cached' the typeof result in a const because it had a chain of ifs checking for different type values.