Enforce TypeScript's compliance with class types

Here is a code snippet that I came across:

class A {
    public var1: string = 'var1';
}

class B {
    public var1: string = 'var1';
    public var2: string = 'var2';
}

const instance: A = new B();
console.log(instance instanceof A);

I am puzzled by the fact that TypeScript allows instance: A = new B() even though B does not extend A. If A and B were interfaces, it would make sense because interfaces are not enforced at runtime, but with classes, I find it confusing.

The outcome of the last line being "false" clearly indicates that A is not B!

Is there a way to address this issue? Perhaps through compiler options or using Generics in the code?...

Thank you.

Answer №1

The explanation for why typescript doesn't display errors when you write const instance : A = new B() is due to its use of structural typing. Essentially, if the structure or shape aligns with each other, typescript accepts it without any issues.

For instance, consider the following scenario:

class A {
  foo() : boolean { return true }
}

class B {
 foo() : boolean { return true }
}

const bar : A = new B()

The typescript compiler views the above code as equivalent because of their similar structures. However, if there's a change in structure, the compiler will identify and flag it.

class AA {
  foo() : boolean { return true }
}

class BB {
 foo() : string { return "true" }
}

const foobar : AA = new BB()

In such cases, tsc will generate an error message like this:

Type 'BB' is not assignable to type 'AA'. The types returned by 'foo()' are incompatible between these types. Type 'string' is not assignable to type 'boolean'

In your example, B mirrors the exact structure of A since public var1: string exists in both classes. Thus, B can be assigned to A. On the contrary,

const instance: B = new A()

the compiler will raise an issue because A doesn't entirely match the structure of

B</code, given that <code>public var2: string
is in B but not in A.

In contrast, C++, Java, and certain other languages employing nominal typing would catch such discrepancies during compilation.

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

Using absolute imports to resolve modules in TypeScript and Next.js

When I import functions from files using absolute imports, I keep encountering errors that I have been trying to resolve. The errors manifest in a certain way, as shown here: https://i.sstatic.net/J7Ai1.png Despite the errors, the functions are successful ...

Trouble encountered when implementing multiple conditions for checkboxes in an Angular 8 application

In my form, there are four checkboxes (3 for options and 1 for setting a plan) which have specific requirements: If all three options are checked, the set plan checkbox is automatically checked and the options disappear If the set plan checkbox is checke ...

Comparing React hooks dependency array with TypeScript discriminated unions

In my React app using TypeScript, I encountered a situation where a component's props type is a discriminated union to prevent invalid combinations of props at compile time. However, I faced a dilemma when trying to pass some of those props into a Rea ...

"Using MatCheckbox's preventDefault() method to access the checked value of the

Is there a way to customize a Material checkbox to prevent it from being checked or unchecked by default (e.g., by calling preventDefault() on the event) and still retrieve the checked value from the event? It appears that achieving both conditions simult ...

Encountered an unexpected * token while importing lodash

Encountering an issue with TypeScript compilation after installing lodash library. To install lodash, run the following commands: 1) npm install --save lodash 2) npm install --save lodash Code snippet: import * as lodash from 'lodash'; class M ...

Ways to identify browser version in Angular 4 to discourage IE usage

Is there a method in Angular 4 (TypeScript) for detecting the browser type? I am currently working with Angular 4 and would like to explore options for identifying the browser type when my application is loaded. I specifically want to prevent my applicati ...

Detecting clicks outside of a component and updating its state using Typescript in SolidJS

Hi there, I am currently learning the SolidJS framework and encountering an issue. I am trying to change the state of an element using directives, but for some reason it is not working. Can anyone point out what I might be doing wrong? You can find the ful ...

Steps for utilizing Bazel to compile TypeScript

Calling all Bazel (Blaze) experts: I'm curious about the best method for integrating Bazel as a build system for cutting-edge web applications built in Typescript. Is there a preferred setup or perhaps a template that demonstrates this integration? T ...

The issue arises when attempting to use the search feature in Ionic because friend.toLowerCase is not a valid function

I keep encountering an error message that says "friend.toLowerCase" is not a function when I use Ionic's search function. The unique aspect of my program is that instead of just a list of JSON items, I have a list with 5 properties per item, such as f ...

Observing a class getter within Vue.js

The issue at hand I am facing a challenge in ensuring my page automatically updates when new data is available. I am using Ionic, and have a page that displays all the items collected by the user in a visually appealing manner using an ion-grid. To achiev ...

What is the correct way to assign a property to a function's scope?

Lately, I've been delving into Typescript Decorators to address a specific issue in my application. Using a JS bridge to communicate TS code between Android and iOS, we currently define functions as follows: index.js import foo from './bar' ...

Explain a TypeScript function that takes an object as input and returns a new object with only the

Check Playground What's the best way to define a type for this specific function? The inputObject should contain all keys from the enablePropertiesArray and may have additional ones. The function is expected to return a copy of the inputObject, inclu ...

Is there a more efficient method for invoking `emit` in Vue's Composition API from an external file?

Is there a more efficient way to access the emit function in a separate logic file? This is my current approach that is functioning well: foo.js export default (emit) => { const foo = () => { emit('bar') }; return { foo }; } When ...

What is the syntax for type assertion in TypeScript using the new statement?

Sample code: new CustomClass<string>() Can you explain the significance of <string>? Does it denote the data type for the initial constructor input? ...

Resolving the issue of missing properties from type in a generic object - A step-by-step guide

Imagine a scenario where there is a library that exposes a `run` function as shown below: runner.ts export type Parameters = { [key: string]: string }; type runner = (args: Parameters) => void; export default function run(fn: runner, params: Parameter ...

Moving a custom folder to production on Vercel with Next.js

I am currently working on developing a project using the NextJS environment. In this project, I have some JSON files stored in a folder within my root directory, and I am reading the content of these files in my code. Everything works fine on my local mach ...

How can I set the default bindLabel for a dropdown in @ng-select/ng-select when the self change event occurs in Angular

I have a scenario where I need to set the default value to null in the ng-select. If the user selects an option from the dropdown first, then on the change event it should check if the Amount model is not null or blank. If the Amount model is blank, then ...

Updates to Angular form control values are not triggering notifications

I am currently working with a basic form control that subscribes to the valueChanges observable. @Component({ selector: 'my-app', template: ` <input [formControl]="control" /> <div>{{ name$ | async | json }}</div ...

Is it possible to retrieve the original array after removing filters in Angular?

Within my component, I have an array that I am filtering based on a search string. The filtering works as expected when the user inputs characters into the search field. However, I am encountering an issue when attempting to display all records again after ...

Difficulty encountered while attempting to iterate through a JSON object using *ngFor

Attempting to compile a list of data fetched from an endpoint, I receive 10 pieces of data and aim to utilize *ngFor to exhibit them. The data is successfully received in the correct order, but an error arises: ERROR Error: "Cannot find a differ support ...