12

I think Interface rarely have both anonymous and named function. Is this right?

TypeScript compiler allows interface to have both anonymous and named function.

// no error
interface Foo {
  (x: number, y: number): number; // anonymous
  namedMethod: (z: string, w: string) => string; // named
}

But it seems unavailable.

// badProp is not assignable
const foo1 : Foo = {
  badProp(x: number, y: number) { return 1 },
  namedMethod(a: string, b: string) { return 'str'; }
}

// syntax error
const foo2 : Foo = {
  (x: number, y: number) { return 1 },
  namedMethod(a: string, b: string) { return 'str'; }
}

using any type, it works.

const temp: any = function (x: number, y: number) { return 1 };
temp.namedMethod = function (a: string, b: string) { return 'str'; }
const foo3: Foo = temp;

Though using both is Technically possible, Interface rarely have both anonymous and named function. Is this right?

1

3 Answers 3

11

An "unnamed" member in a TypeScript interface does not refer to an anonymous member, but declares the function signature of the interfaced class itself, as described in this section of the documentation.

For example:

/**
 * Interface for function that takes two numbers as arguments, and returns
 * a number.
**/
interface TwoNumberFunction {
    (x: number, y: number): number,
}

// simple function: adds two numbers
function add(x: number, y: number): number {
    return x + y;
}

// 'add' is a function that takes two numbers and returns a
// number, so it matches the interface's requirements:
const func: TwoNumberFunction = add;
func(1, 2); // = 3
Sign up to request clarification or add additional context in comments.

Comments

9

TypeScript allows interfaces to have hybrid types, i.e. interfaces can have a combination of properties, function declarations, indexer and methods. This flexibility is allowed to get aligned with JavaScript dynamic nature.

interface Foo {
    (x: number, y: number): number; // anonymous
    namedMethod: (z: string, w: string) => string; // named
    randomNumber: number
}

const foo2 = ((x: number, y: number) => x+ y + 1) as Foo;
foo2.namedMethod = (z: string, w: string) => z;
foo2.randomNumber = 4
console.log(foo2(1, 3)); // prints 5
console.log(foo2.namedMethod('hello', 'world')); // prints 'hello'
console.log(foo2.randomNumber); // prints 4

Watch this video to know what is hybrid types in typescript?

Comments

3

there is two way to write Function types. https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#334-function-types is helpful.

1. call signatures in object type literals.

https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#392-call-signatures

// call signatures is like this.
(x: number, y: number): number,

interfaces to declare function types

spec says that

Since function and constructor types are just object types containing call and construct signatures, interfaces can be used to declare named function and constructor types.

so I can write this.

// interface with call signatures
interface TwoNumberFunctionInterface {
  (x: number, y: number): number,
}

2. function type literal.

https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#388-function-type-literals

// function type literal is like this
let a: (x: number, y: number) => number;

function type literal is shorthand for an object type containing a single call signature.

// object type containing a single call signature
let a: {(x: number, y: number): number};

1 Comment

"Call signature" was the keyword I was looking for, and allowed me to find this answer for how to extract just the call signature from an interface (and exclude properties, etc.).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.