Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript not checking function argument types declared by interfaces

Tags:

typescript

I was expecting TWO errors when compiling the code below, but typescript compiles it without any errors.

interface IFoo{
    Bar(callback: (arg:string) => void):void;
}

class Foo implements IFoo {
    public Bar(callback: () => void):void{
        callback();
    }
}

var foo: IFoo;
foo = new Foo();
foo.Bar(() => {
    console.log("Hi");
})

Expected Error 1: IFoo.Bar requires a function argument which itself takes a string argument. However, when Foo implements IFoo, Foo.Bar is declared to take a function argument with NO arguments. I would expect this to be a type error.

Expected Error 2: foo is of type IFoo. foo.Bar is called with a function argument that takes no arguments, contrary to the definition of Bar in IFoo. I would expect this to be a type error.

So both when declaring a concrete implementation of an interface method, and also when calling the interface method, it seems that the type of the function signature is not being enforced.

Clearly I am misunderstanding how typescript handles type checking of function arguments declared by an interface. Can someone explain why this compiles without error?

like image 712
RJM Avatar asked Feb 21 '16 19:02

RJM


People also ask

How do you define a function in interface TypeScript?

TypeScript Interface can be used to define a function type by ensuring a function signature. We use the optional property using a question mark before the property name colon. This optional property indicates that objects belonging to the Interface may or may not have to define these properties.

How do you declare arguments in TypeScript?

We can declare it by prefixing the three "dot" characters ('...') before the parameter. It allows the functions to have a different number of arguments without using the arguments object.

How do you pass a function as a parameter in TypeScript?

Similar to JavaScript, to pass a function as a parameter in TypeScript, define a function expecting a parameter that will receive the callback function, then trigger the callback function inside the parent function.

Does TypeScript enforce types?

Bookmark this question. Show activity on this post. I had an impression that TypeScript allowed you to take a valid JavaScript program and "enforce" types by making a few key symbols type-safe.


1 Answers

This is answered in the TypeScript FAQ. Here is the text of that answer:

This is the expected and desired behavior. First, refer to the "substitutability" primer at the top of the FAQ -- handler is a valid argument for callback because it can safely ignored extra parameters.

Second, let's consider another case:

let items = [1, 2, 3];
items.forEach(arg => console.log(arg));

This is isomorphic to the example that "wanted" an error. At runtime, forEach invokes the given callback with three arguments (value, index, array), but most of the time the callback only uses one or two of the arguments. This is a very common JavaScript pattern and it would be burdensome to have to explicitly declare unused parameters.

like image 82
Ryan Cavanaugh Avatar answered Sep 22 '22 23:09

Ryan Cavanaugh