question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Type inference/narrowing lost after assignment

See original GitHub issue

TypeScript Version: 3.1

Search Terms: type inference, type guard, narrowing, lost, assignment

Code

let a: unknown = 'x';

if (typeof a === 'string') {
  // a inferred as `string`
  a = a.substr(0, 5);  // (method) String.substr(from: number, length?: number): string
  // a inferred as `unknown`
  a.length;            // Failure: Object is of type 'unknown'.
}

Expected behavior: This should compile without an error.

Actual behavior: Line 7 fails with: Object is of type 'unknown'.

Playground Link: https://www.typescriptlang.org/play/index.html#src=let a%3A unknown %3D ‘x’%3B if (typeof a %3D%3D%3D ‘string’) { %2F%2F a inferred as `string` a %3D a.substr(0%2C 5)%3B %2F%2F a inferred as `unknown` a.length%3B }

Related Issues: #18840, #19955, #26673

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:13
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
AlCalzonecommented, Feb 7, 2021

I just stumbled into this aswell, albeit with number instead of string. I can’t see any logical reason why assigning a number to a value we know for sure to be a number should require us to narrow again:

declare function takesNumber(value: number): void;

function test(value: unknown) {
  if (typeof value !== "number") return;
  takesNumber(value); // ok
  value = 1; // assign the same type!
  takesNumber(value); // error (value is unknown, although we narrowed it to number before)
}

I would really love to have an unknown type that is less cumbersome to work with. It has been really awkward since it was introduced almost 3 years ago and not much has changed 😦.

0reactions
corymharpercommented, Apr 25, 2022

I also ran into this issue today while trying to use unknown. It’s rather fine that assignment itself doesn’t narrow types, that would just be nice. However, the unintuitive part for me is that it actually broadens an already narrowed type. So if I have type checked that I am working with an array, if at any point I do a reassignment on that variable, I’ll lose the narrowing that has already been done and have unknown again. I’m left with the option of creating a new variable after doing the type narrowing and assigning it to the now narrowed variable, then the type for that variable will be inferred as the correct type, which is just really awkward and creates unneeded variables.

For arrays in Javascript this is particularly noticeable if you have broken down multiple method calls onto separate lines using reassignments, you just can’t do it if the variable was originally of type unknown.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Documentation - Narrowing - TypeScript
This analysis of code based on reachability is called control flow analysis, and TypeScript uses this flow analysis to narrow types as it...
Read more >
Type-Safe TypeScript with Type Narrowing - Rainer Hahnekamp
Whenever we deal with a variable that can be of multiple types, like an unknown or a union type, we can apply type...
Read more >
Infer narrow type from parent object referencing itself in ...
I have all this already set up with narrow type inference to not make any mistakes while writing each action but this narrow...
Read more >
narrowing types via type guards and assertion functions - 2ality
Inside the then-blocks starting in line A and line B, the static type of value changes, due to the checks we performed. We...
Read more >
Master Type Narrowing In Typescript - Nicos Tsourektsidis
How do we narrow down a type to more specific ones? ... Combine this with type inference and you get pretty sophisticated error...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found