简体   繁体   中英

Interface function with some properties (TypeScript)?

How can I use following interface?

interface Something {
 (n: number): void,
 description: string
}

I try writing following.

var sth: Something = {
    description: "Description"
}

sth = (n: number) => {
    console.log("Something");
}

or

var sth: Something = {
    (n: number) => {
        console.log("Something");
    },
    description: "Description"
}

But they both give errors.

You cannot directly create an object which is both a function and has other properties. You have to do it in two steps, first create a function, then assign it another prop, then assign the result to a variable of your interface:

interface Something {
  (n: number): void;
  description: string;
}

function fn(n: number) {}

fn.description = 'foo';

const h: Something = fn;

You can do it in one of few ways. Each fits slightly odd with functions with properties but all are viable, depending on the use case:

Create the function then add the property

There is no syntax for creating a function with a property. You have to do both separately:

var sth: Something = ((n: number) => {
    console.log(n + 2);
}) as Something;
sth.description = "Description";

Playground Link

The as Something assertion is needed here to tell the compiler to treat the function as Something , otherwise you cannot add the description .

Object.assign()

This allows declaring everything at once:

var sth: Something = Object.assign(
  (n: number) => {
    console.log(n + 2);
  },
  { description: "Description"}
);

Playground Link

Object.assign is typed to return any so the type declaration sth: Something makes sure it is treated as the correct object afterwards.

Object.defineProperty()

Another way to create an object and add a property. It allows more control over the property, like making it non-writable, if needed.

var sth: Something = Object.defineProperty(
  (n: number) => {
    console.log(n + 2);
  },
  "description",
  { value: "Description"}
) as Something;

Playground Link

The as Something assertion is needed because Object.defineProperty() is typed to return the same as the first argument. So it returns (n: number) => void .

Object.defineProperties()

Very similar to Object.defineProperty() but allows multiple properties to be configured at once.

var sth: Something = Object.defineProperties(
  (n: number) => {
    console.log(n + 2);
  },
  { 
    description: { value: "Description" }
  }
) as Something;

Playground Link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM