Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

TypeScript: Annotate `is string` instead of `boolean`?

It seems to me that TypeScript interprets typeof x === 'string' not only as a simple boolean, but as some kind of a boolean is string type.

Consider this example:

const tryInference = function(maybeStr?: string): void {

  const isStrI          = typeof maybeStr === 'string'; // inferred type "is string"
  const isStrB: boolean = typeof maybeStr === 'string'; // explicit boolean

  console.log( isStrI && maybeStr.charAt(0) ); // <-- ok
  console.log( isStrB && maybeStr.charAt(0) ); // <-- TS18048: 'maybeStr' is possibly 'undefined'.

  const indeedStr1: string = isStrI ? maybeStr : ''; // <-- ok
  const indeedStr2: string = isStrB ? maybeStr : ''; // <-- TS2322: Type 'string | undefined' is not assignable to type 'string'

  console.log( indeedStr1, indeedStr2 );
};

I understand that in case of isStrI TypeScript knows that if typeof maybeStr === 'string' then maybeStr.charAt is available.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I suppose that in case of isStrB && maybeStr.charAt(0) TypeScript interprets it as true && maybeStr.charAt(0), and doesn’t have the relation to the typeof maybeStr === 'string' anymore ? (if isStrB is true, of course)

That makes me wonder:

  1. Can I annotate isStrI explicitly somehow, without destroying the information that maybeStr is of type string ?

  2. Am I right with my assumptions ? Does somebody have a more detailed explaination ?

>Solution :

This isn’t currently possible.

The support for control flow analysis of aliased conditions as implemented in microsoft/TypeScript#44730 doesn’t occur at the type level in a way you can manipulate programmatically. The type of the variable is just boolean either way; no type annotation could capture its relationship to maybeStr (type predicates do not exist as standalone types). And furthermore, annotating the variable destroys the relationship:

Narrowing through indirect references occurs only when the conditional expression or discriminant property access is declared in a const variable declaration with no type annotation [emphasis added], and the reference being narrowed is a const variable, a readonly property, or a parameter for which there are no assignments in the function body.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading