How is it possible that a string type is present in the else block of the code after being processed in the if block?

While studying about equality narrowing in typescript, I came across a function example from the official handbook (view it on playground):

function example(x: string | number, y: string | boolean) {
  if (x === y) {
    // We can now call any 'string' method on 'x' or 'y'.
    // As x and y can only be equal if they had type string
    x.toUpperCase();
    y.toLowerCase();
  } else {
    console.log(x);     // x : string | number

    console.log(y);     // y : string | boolean
  }
}

In the if branch, both x and y are narrowed down to type string. This allows us to use string methods. However, in the else branch, both x and y still have string as a possible type. Ideally, string should not be present as a type in the else branch. Is this a limitation of Typescript's current type system, or am I missing something crucial here? Your insights would be greatly appreciated. Thank you!

Answer №1

It would be ideal for the string type not to appear in the else branch

Yes, they could - if both are strings, but not if the strings are not ===.

function example(x, y) {
  if (x === y) {
    // this branch won't get executed
  } else {
    console.log(typeof x); // string
    console.log(typeof y); // string
  }
}

example('foo', 'bar');

The narrowing you're expecting would happen if you used typeof checks with ||, although it wouldn't guarantee that both values are strings in the first branch.

function example(x: string | number, y: string | boolean) {
  if (typeof x === 'string' || typeof y === 'string') {
  } else {
    console.log(x);
    //          ^? number
    console.log(y);
    //          ^? boolean
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Changing Angular code to vanilla JavaScript

Here is an example code snippet for a plugin used in an Ionic/Capacitor/Angular project: import { ForegroundService } from '@awesome-cordova-plugins/foreground-service/ngx'; constructor(public foregroundService: ForegroundService) { } ... sta ...

Creating a Fixed-length Array in TypeScript

Seeking assistance with TypeScript types, I have a particular question. When declaring a type for an array as follows... position: Array<number>; ...it allows for creating an array of any length. However, if you need an array containing numbers of ...

React-aria | Encountering a typescript error with input fields/textfields

Seeking assistance with using react-aria, specifically the useTextField feature. Despite following the documentation available at , I encountered an error related to the input element. Any help would be appreciated. Code import { AriaTextFieldOptions, use ...

Unlocking $refs with the Composition API in Vue3 - A step-by-step guide

I am currently exploring how to access $refs in Vue 3 using the Composition API. In my template, I have two child components and I specifically need to obtain a reference to one of them: <template> <comp-foo /> <comp-bar ref="ta ...

Troubleshooting property assignment issues within an Angular service

I have created a simple injectable service in TypeScript for Angular 4. This service is designed to fetch a JSON file from the network and store the data as an array in its property called data. Other classes can then access this data using the method getD ...

Learn how to successfully import a webp image into a React TypeScript project

I have looked everywhere for the answer, but I can't seem to find it When trying to import a *.webp image in typescript, you need to create a declaration file, like declaration.d.ts The declaration file should contain something similar to the foll ...

What kind of reacttypescript are prop types usually?

Having trouble with describing incoming props for a child element and encountering this error message Error: Parameter 'props' implicitly has an 'any' type.ts(7006) (parameter) props: any // Example of Parent Element <GeneralBut ...

Using super() conditionally in Typescript

Is it possible to conditionally load the super class based on a parameter in TypeScript? I am facing an issue where I need to send a parameter in super() based on a specific condition, but placing an if statement before super() results in a compilation err ...

React-pdf has encountered a situation where more hooks were rendered compared to the last render cycle

I am currently integrating react-pdf to display a PDF document in a web view. The React application is built with TypeScript and Next.js. This is the code I have written so far: const MyPage: NextPage = () => { // some code here const [numPages, setN ...

Enhance your React Native experience with IntelliSense recommending react-native/types over react-native

I am trying to bring in <View from react-native, but instead, I am getting react-native/types https://i.sstatic.net/FeRKT.png How can I resolve this issue? This is a new project starting from scratch and I followed the documentation by adding TypeScri ...

Combine two arrays of data sources

mergeThreads() { const userId = this.auth.getUser().uid; const buyerThreads$ = this.afs.collection('threads', ref => ref.where('buyerId', '==', userId)).valueChanges(); const sellerThreads$ = this.afs.collection ...

What happens when a CSS module is exported as an empty object?

My go-to for creating projects is using TypeScript and create-react-app. I recently incorporated the typings-for-css-modules-loader and dabbled in css-modules as well. { test: /\.css$/, use: [ require.resolve('style-loader'), { ...

What is the reason for the presence of additional mandatory dependencies in the package-lock.json file?

The recent release of React includes breaking changes to the TypeScript typings, causing packages that require "@types/react" with a wildcard version to automatically target this new version and break my project. Initially, I wanted to reach out to projec ...

What is the best way to iterate through two object keys in TypeScript?

I recently created a Vector class but I am encountering some issues with the syntax. Here is the code snippet: export class Vector { x: number; y: number; constructor(x = 0, y = 0) { this.x = x; this.y = y; } add(v: Vector) { var x ...

Establishing a server in Node.js alongside an Angular 2 frontend by harnessing the power of Typescript

I'm looking to deploy my web application on IBM Bluemix with Angular 2 using Typescript for the frontend and Node.js for the backend. Can you advise me on how to configure the server, connect it to the frontend, and specify which transpiler I should u ...

A versatile Material UI paper that adjusts its dimensions dynamically

Utilizing Material-UI's Paper component (https://mui.com/components/paper/), I've encountered a scenario where the content within the Paper element needs to be dynamic. <Paper className="modal" elevation={3}> ...Content </Paper ...

Whenever attempting to execute a protractor test using cucumber, a specific error message is displayed reading: "E/launcher - Process exited with error code 1"

Looking for some assistance. I seem to be stuck and can't pinpoint the issue. Package.json { "devDependencies": { "@cucumber/cucumber": "^7.0.0", "@serenity-js/core": "^2.25.7", "@s ...

An issue occurred in the modal window following the relocation of project files

I encountered an issue with the modal in my Nativescript project after rearranging a few project files, including the modal. I updated the imports and deleted any compiled JavaScript files to ensure that my project could recompile correctly. Although I&ap ...

What is the best way to display data in the view using Angular 5 by utilizing models, classes, or interfaces?

I am facing an issue while trying to display the data fetched from my backend. I have created a class to handle the data: When I request the User by ID URI, the returned data looks like this: https://i.sstatic.net/76BSY.jpg Similarly, when I request all ...

What is the best way to retrieve URL parameters in Node.js using TypeScript?

In the onRequest method provided below, I encounter an error: onRequest(request: Http.IncomingMessage, response: Http.ServerResponse): void { response.writeHead(200, {"Content-Type": "text/plain"}); const tc = new TaxCalculator(); ...