Are your custom guards failing to function properly now?

Previously, the code below was functioning properly until typescript 2.0:

class Aluno{
  escola: string;
  constructor(public nome: string){
    this.escola = "";
  }
}
class Pessoa{
  morada: string;
  constructor(public nome: string){
    this.morada = "";
  }
}
function ePessoa(p: Pessoa | Aluno): p is Pessoa{
  return (<Pessoa>p).morada !== undefined;
}
function eAluno(p: Pessoa | Aluno): p is Aluno{
  return (<Aluno>p).escola !== undefined; 
}
let a: Pessoa | Aluno = new Pessoa("Luis");
console.log( a.nome ); //works fine
a = new Aluno("Rui");
console.log( a.nome ); //works fine as well
//a.escola = "teste";//error occurs here
if(eAluno(a)){
  console.log("Student at school:" + a.escola);
}
else{
  console.log("Person residing in: " + a.morada); //morada does not exist
}

The compiler is not recognizing 'a' as a Person in the else branch. Am I overlooking something?

Answer №1

The error message states:

Property 'morada' does not exist on type 'never'

This error occurs because the compiler recognizes that the else clause is never accessed.

In your code snippet, you have:

let a: Pessoa | Aluno = new Pessoa("Luis");
...
a = new Aluno("Rui");

Therefore, at the if statement, a will always be of type Aluno, never Pessoa.

You can learn more about the never type here.


Edit

The purpose of TypeScript is to prevent developers from making mistakes.
While some JavaScript developers argue that types are unnecessary, you are still utilizing TypeScript.

The error you encountered is akin to an Unreachable code error:

function fn(): boolean {
    return false;

    let a = 3; // Error: Unreachable code detected
}

(Try it in the playground)

Why include code that will never run?
It adds unnecessary complexity and maintenance burden, without any benefit.


2nd edit

The compiler only checks for errors within the current scope, like with the Unreachable code error:

function fn(): boolean {
    throw new Error("error");
}

let a = fn();
if (a) { // no error
    console.log("all good");
}

However:

let a = fn();
throw new Error("error");
if (a) { // Error: Unreachable code detected
    console.log("all good");
}

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

Fetching all data from a SQLite database in a Listview using React Native

I have been utilizing the library found at https://github.com/andpor/react-native-sqlite-storage in my react native project. To retrieve a single row from the database, I use the following code: db.transaction((tx) => { tx.executeSql('SEL ...

SonarQube alerting you to "Eliminate this unnecessary casting"

Can someone help me understand why SonarQube is flagging this error and suggest a resolution? The unnecessary cast should be removed. Promise.all([ this.customerViewCmr4tProvider.getData(activeNumber), this.customerBillManagementProvider.getData(ind ...

Transform object properties into key-value objects using Typescript generics

When I receive a sorting object with a columnName and direction, I want to convert it into a key-value object for mongoose sorting. The return values are not matching up and I can't seem to figure out what I'm missing. These are the interfaces ...

Understanding the functionality of imports within modules imported into Angular

I have been scouring through the documentation trying to understand the functionality of the import statement in JavaScript, specifically within the Angular framework. While I grasp the basic concept that it imports modules from other files containing expo ...

Retrieve information using Angular's EventEmitter

Recently I started learning Angular and encountered a challenging issue that has kept me occupied for the past few hours. I have implemented a parent-child relationship between two components, with a need to share a boolean variable from the parent to the ...

Ionic 3: Struggling to Access Promise Value Outside Function

I've encountered an issue where I am unable to retrieve the value of a promise outside of my function. It keeps returning undefined. Here's what I have attempted so far: Home.ts class Home{ dd:any; constructor(public dbHelpr:DbHelperProvider ...

The function threw an error: "TypeError: this.registeredUserArray.some is not a function"

I have been attempting to store a registered user object inside localstorage. However, when I try to retrieve or set those values from localstorage in an array and parse it back to an object, I encounter an error stating that ".push" or ".some" is not a ...

How to efficiently mock the $window object in Angular unit tests

Attempting to unit test an angular custom service written in Typescript has been a challenge for me. The service is designed to read a global variable defined on the Window object and I have made it promise-based for potential future AJAX calls. Below is a ...

Utilize a vacant implementation of an interface

I have a simple interface called EmployerContact. I'm wondering how I can create an empty object, mockEmployerContact, of type EmployerContact and then assign values to its properties later on. Do I need to start with default values for this object? e ...

The error message related to TupleUnion in TypeScript is indicating that the depth of type instantiation may be too deep and could

Recently, I've been delving into a TypeScript utility type known as TupleUnion. This useful type came to my attention through a fascinating Twitter post, and I've observed it being utilized in various Stack Overflow solutions. Here's how the ...

Ways to enhance TypeScript definitions for Node.js modules

Using the nodejs module "ws", I installed typings using typings i dt~ws import * as WebSocket from "ws"; function add(client:WebScoket){ let cid = client.clientId; } I am trying to Expand the WebSocket object with a property called clientId, but I&a ...

Why is the removal of this type assertion in TypeScript causing an issue?

Why is TypeScript refusing to compile this code snippet? interface TaggedProduct { tag: string; } interface Product { tag?: string; } const tagProduct = (product: Product): TaggedProduct => { const tag: string = "anything"; pro ...

Creating a dynamic visual experience with Angular 2: How to implement multiple font colors

I have a text area which is connected to one string, with the default text color set to white. <textarea style="background-color: black;color:#fff;" [(ngModel)]="outputText"></textarea> The connected string contains multiple variables. retur ...

obtaining the value of an input using typescript (put request)

Does anyone know how to extract input values and store them as JSON? I'm having trouble with accessing the input value in this scenario. When I attempt document.querySelector("todo-text").value, it results in an error. const NewTodo: React.FC<NewT ...

Is there a way to retrieve a particular object from a versatile function?

Here is a generic function to consider: public getData<T>(url: string): Observable<T> { return this.httpClient.get<T>(url); } I am looking for a way to test this function by returning a mock object array, especially if the remote ...

Angular is not able to access the value of a promise in a different function after it has been retrieved

I have a form with default values that should be added to the form fields when it appears. There are two functions: #1 for fetching data from the backend and #2 for displaying the form: person$: any; ngOnInit() { this.getPersonData(123) this.buildPer ...

Simple steps to transform the "inputs" syntax into the "@Input" property decorator

There's this code snippet that I need to modify: @Component({ selector: 'control-messages', inputs: ['controlName: control'], template: `<div *ngIf="errorMessage !== null">{{errorMessage}}</div>` }) Is the ...

Angular - handling Observable<T> responses when using Http.post

One issue I encountered was when trying to implement a method that returns an Observable. Within this method, I utilized http.post to send a request to the backend. My goal was to store the JSON object response in an Observable variable and return it. Howe ...

I encountered a mistake: error TS2554 - I was expecting 1 argument, but none was given. Additionally, I received another error stating that an argument for 'params' was not provided

customer-list.component.ts To load customers, the onLoadCustomers() function in this component calls the getCustomers() method from the customer service. customer.servise.ts The getCustomers() method in the customer service makes a POST request to the A ...

I'm curious about how to implement textarea functionality within Angular for modeling purposes

I have a desire to utilize the model and transmit it to the server. One instance of this is sending comments. comment.model.ts export interface Comment { article_no: number; username: string; nickname: string; creatat: Date; content: string; } ...