Declare a function with an Object return type in TypeScript

avatar

Borislav Hadzhiev

Last updated: Feb 24, 2022

banner

Photo from Unsplash

Declare a function with an Object return type in TypeScript #

To declare a function with an object return type, set the return type of the function to an object right after the function's parameter list, e.g. function getObj(): {name: string;} {}. If the return type of the function is not set, TypeScript will infer it.

index.ts
// ✅ named function function getObj(): { name: string; age: number } { return { name: 'Tom', age: 30 }; } // ✅ arrow function const getObj2 = (): { name: string; age: number } => { return { name: 'Tom', age: 30 }; }; // ✅ class method class A { getObj(): { name: string; age: number } { return { name: 'Tom', age: 30 }; } } // ✅ Using interface interface Person { name: string; age: number; } function getObj3(): Person { return { name: 'Tom', age: 30 }; }

You can set the return type of a function right after its parameter list.

index.ts
interface Person { name: string; age: number; } function getObj4(name: string, age: number): Person { return { name, age }; }

The examples above show how to set the return type of a function to an object that contains a name and age properties.

The advantage of setting the return type of the function explicitly is that the type checker would throw an error if you try to return an object of a different type.

index.ts
interface Person { name: string; age: number; } function getObj3(): Person { // ⛔️ Error: Object literal may only // specify known properties, and 'country' // does not exist in type 'Person'.ts(2322) return { name: 'Tom', age: 30, country: 'Chile' }; }

If you don't explicitly set the return type of the function, TypeScript will infer it.

index.ts
// 👇️ function getObj3(): {name: string; age: number; country: string;} function getObj3() { return { name: 'Tom', age: 30, country: 'Chile' }; }
When setting the return type of a function to an object, you might not know all of the properties the object will have.

If that's the case, you can use an index signature.

index.ts
interface Person { name: string; age: number; [key: string]: any; // 👈️ index signature } function getObj3(): Person { return { name: 'Tom', age: 30, country: 'Chile', city: 'Santiago' }; }

An index signature is used when we don't know all of the names of a type's properties and the type of its values ahead of time.

The index signature in the examples means that when an the object is indexed with a string, it will return a value of any type.

You might also see the index signature {[key: string]: string} in examples. It represents a key-value structure that when indexed with a string returns a value of type string.

We still get type safety for the properties that we know about in advance.

For example, the name and age properties have to exist on the object the function returns and have to be of specific type.

If you try to omit the properties or set them to an incorrect type, you'd get an error.

index.ts
interface Person { name: string; age: number; [key: string]: any; } function getObj3(): Person { // ⛔️ Error: Type 'number' is not assignable // to type 'string'.ts(2322) return { name: 100, age: 30, country: 'Chile', city: 'Santiago' }; }

We passed a number for the name property, so the type checker threw an error.

You should only use this approach when you don't know the names of all of the objects keys ahead of time.

It's always best to be as explicit as possible and write the most type safe code.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.