Ashish Singh
Ashish Singh

Reputation: 1079

Type Checking in Hybrid Interfaces

This is an example as mentioned in the TypeScript handbook here -

Hybrid Types

As we mentioned earlier, interfaces can describe the rich types present in real world JavaScript. Because of JavaScript’s dynamic and flexible nature, you may occasionally encounter an object that works as a combination of some of the types described above.

One such example is an object that acts as both a function and an object, with additional properties:

interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}

function getCounter(): Counter {
    let counter = <Counter>function (start: number) { };
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}

let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

If I modify the type casting line in function getCounter to this, the compiler still verifies it as good.

let counter = <Counter>{ };

But if you run the compiled JavaScript, it will give error as counter is not really a function now but an Object.

Question - Should the TypeScript compiler give any error in this case or is it correct as a function is a sub type of an Object?

The link to editor is here

Upvotes: 2

Views: 179

Answers (2)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249466

Type assertions are used to tell the compiler to ignore the type it knows in favor of the type you tell it. If you are wrong about the assertion you make the compiler cannot warn you about it. There are definitely types in Typescript when you will need to do this but if you can find a type safe way to do the equivalent it would be better. In this case you could use Object.assign:

function getCounter(): Counter {
    let counter = Object.assign(function (start: number) {  return ""}, {
        interval: 123,
        reset: function () { }
    });
    return counter;
}

Upvotes: 2

Matthias247
Matthias247

Reputation: 10396

The < > operator is a forced type assertion/cast. You are telling the compiler to ignore everything it knows about the object, and to just assume it's the type which is specified inside the angle brackets. So from the Typescript compiler side everything is fine. Which means from usage side you should only fall back to those casts if you are absolutely sure that the type is correct.

More information in the Type assertions section here: https://www.typescriptlang.org/docs/handbook/basic-types.html

Upvotes: 1

Related Questions