Is TypeScript designed to accommodate duck typing?

There seems to be conflicting information on this topic. https://basarat.gitbooks.io/typescript/content/docs/classes.html (go to the inheritance section) suggests that it's supported, but I'm encountering compilation issues with my TypeScript code on playGround

class Point{
    x:number; 
    y:number;
    constructor(x:number, y:number){
    this.x = x;
    this.y = y ;    
    }

    add(point:Point){
     return new Point(this.x + point.x , this.y + point.y);
    }
}

class Point3D extends Point{
    z:number;
    constructor(x:number, y:number, z:number){
        super(x,y);
        this.z = z;
    }

    add(point3d:Point3D){
        // Error does not support duct type.
        var point2D = super.add( {point3d.x, point3d.y}); 
        return new Point3D(point2D.x, point2D.y, this.z);
    }
}

Answer №1

It won't suffice in your scenario to simply pass the Point instance as is:

add(point3d:Point3D){
    // Error does not support duct type.
    //var point2D = super.add( {point3d.x, point3d.y}); 

    var point2D = super.add(point3d);

This is because super only accepts points

add(point:Point){...

And Point3d is a Point

class Point3D extends Point{

Take a look at the updated playground

If we want to fully utilize duck typing, we should introduce an interface

interface IPoint{
    x:number; 
    y:number;
}

and use that in the add method

add(point:IPoint){
 return new Point(this.x + point.x , this.y + point.y);
}

Then, we can implement duck typing like this:

var point2D = super.add({x: point3d.x, y: point3d.y});

Check out the example here

Answer №2

Contrary to popular belief, TypeScript is not actually considered to be duck typed. Instead, it falls into the category of being structurally typed. The distinction lies in the fact that duck typing only focuses on the specific members accessed during runtime, while structural typing mandates adherence to the complete contract of an object in order to function as a specific interface or type.

For example, when passing an object like {x: point3d.x, y: point3d.y} in TypeScript, it must align structurally with the Point interface. In this case, it fails to meet the requirements as it lacks the necessary add-method.

Answer №3

When attempting to define an object as {x:number, y:number} and label it as a Point, it's important to note that a Point actually consists of

{x:number, y:number, add:(point:Point)=>Point}
. To make this work, make sure to include an 'add' property with a matching signature.

Answer №4

Here is a breakdown of the situation:

  1. The syntax is incorrect. Instead of {point3d.x, point3d.y}, it should be {x: point.x, y: point.y} to create an object.
  2. Duck typing is not possible in this scenario due to the absence of an add method in your object. The compiler will throw an error. To address this, I introduced an interface named IPoint to meet the compiler's requirements.

Take a look at my proposed solution below:

interface IPoint {
    x: number;
    y: number;
}

class Point {
    x: number;
    y: number;
    
    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    add(point: IPoint) {
        return new Point(this.x + point.x, this.y + point.y);
    }
}

class Point3D extends Point {
    z: number;
    
    constructor(x: number, y: number, z: number) {
        super(x, y);
        this.z = z;
    }

    add(point: Point3D) {
        const point2D = super.add({ x: point.x, y: point.y });
        return new Point3D(point2D.x, point2D.y, this.z);
    }
}

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

The array is filled with values, however, there seems to be an issue preventing their access. What could possibly be causing this obstacle

After receiving two string values through a callback function, let's call them a and b, I attempt to store them in an array. However, when I check the array using console.log, it only displays the values if I expand the array by clicking on the arrow ...

What is the best way to populate an Angular variable in Ionic following a subscription?

Currently, I am in the process of retrieving data from a server and displaying it on an Ionic page. I have successfully fetched the data without any issues and verified it in the console. However, how do I proceed once the server returns the data to me? T ...

I would appreciate it if someone could explain the significance of the image display area

Please add a description for this image The table presented below outlines different declaration types: Declaration Type Namespace Type Value Namespace X X Class X X Enum X X Interface X Type Alias X Function X Variable X A ...

Understanding how types intersect in TypeScript

I'm currently diving into Type Relations in TypeScript. Can someone help explain what happens when we intersect the types represented by these two expressions: {a:number}[] & {b:string}[] Does this result in {a:number, b:string}[] ? Any clarificat ...

Omit functions from category

This question reminds me of another question I came across, but it's not quite the same and I'm still struggling to figure it out. Basically, I need to duplicate a data structure but remove all the methods from it. interface XYZ { x: number; ...

Experiencing Compatibility Issues: Next.js 14.0.3 with next-auth and NestJS Backend Runs Smoothly in Development Environment, but Encounters

Currently, I am developing a Next.js 14.0.3 application that utilizes next-auth for authentication. The application interacts with an external NestJS backend for authorization and JWT validation. While everything functions correctly in the development envi ...

Displaying data-table with only the values that are considered true

Right now, I am utilizing the AgReact table to exhibit data fetched from my endpoints. The data-table is functioning properly, however, it seems to be unable to display false values received from the endpoints on the table. Below are the snippets of my cod ...

When using Next.js, I have found that the global.css file only applies styles successfully when the code is pasted directly into the page.tsx file. However, when attempting to

I recently started exploring nextjs and came across this video "https://www.youtube.com/watch?v=KzqNLDMSdMc&ab_channel=TheBraveCoders" This is when I realized that the CSS styles were not being applied to HeaderTop (the first component cre ...

Encountering issues with `Partial<this['someProperty']>` usage in TypeScript

Provided class A { props: { bool?: boolean, test: string } = { test: 'a' }; setProps(newPropertiesr: Partial<this['props']>) { } a() { this.setProps({ bool: fals ...

Why does the pound symbol in z-index always show up in Angular?

Having an issue with my code where I set a z-index in the CSS like this: .mat-mini-fab { position: absolute; right: 5px; top: 4px; z-index: 999; box-shadow: none !important; } However, whenever I visit my site, the z-index is not being appl ...

What is the best way to specify the type of a property that has already been assigned

I am currently utilizing a third-party library that includes a type defined as the following: export interface ThirdPartyNodeType { id: string; name: string; data: any; } Upon further exploration, I have identified the content that I intend to include ...

mat-table dataSource is not functioning properly with REST API integration

I'm facing an issue while trying to populate a Material Table with data. My model Block has fields such as id, date, etc. The API call is made in data.service and the function getAllBlock() fetches the blocks. I tested this in the app.component.html ...

Combining two observables into one and returning it may cause Angular guards to malfunction

There are two important services in my Angular 11 project. One is the admin service, which checks if a user is an admin, and the other is a service responsible for fetching CVs to determine if a user has already created one. The main goal is to restrict ac ...

Struggling to successfully map angular model data to a Spring POJO class

I am currently having issues mapping an Angular model class to my Spring model class. When I try to do so, all the entities in the Spring model class show up as null. I have included the code snippets below that I used for mapping, but unfortunately, it fa ...

Leveraging the Angular (2) routerLinkActive directive to handle dynamic routes

Although my current approach works, I believe there may be a more efficient way to implement this in Angular. The situation is as follows: Imagine nested, inflected paths like /logos and /logo/:id The markup below functions as intended: <li class ...

Trigger event when the useRef element's height surpasses zero

I have a large list of photo thumbnails, and I need to ensure that one of the thumbnails scrolls into view when the list is loaded. The photos are generated using the map function, and the container div of one of the thumbnails will be assigned a ref. I ...

The Angular Animation constantly resets with each new action taken

In my Angular project, I am working on a scaling animation for a list. I want the animation to only trigger when specific buttons (red and green) are pressed. Currently, the animation restarts regardless of what I click on. Can anyone help me troubleshoot ...

I am facing an issue with the Angular2 Modal Form where it only displays the data but does

Hey there, I recently started diving into Angular and I'm loving the learning process. Currently, I've managed to successfully load a form into my Modal when clicking on "viewDetails". However, as soon as I modify the Form from <form ngNoFo ...

What is the method for importing the merge function from "lodash/merge" in TypeScript?

When using ES6, it's possible to import only a single function from a library in order to reduce the overall bundle size. For example: import merge from "lodash/merge" But in TypeScript, the statement above can trigger a compile error: Cannot find m ...

Tips for utilizing withNavigation from react-navigation in a TypeScript environment

Currently, I am working on building an app using react-native, react-navigation, and typescript. The app consists of only two screens - HomeScreen and ConfigScreen, along with one component named GoToConfigButton. Here is the code for both screens: HomeSc ...