Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in Typescript, what is the proper way to define type which is a subset of the actual value?

Tags:

typescript

As per the title.

In my Ionic 2 (Angular2 / TS) app I'm using a cordova plugin (geolocation) which returns a set of fields which include latitude and longitude (but also other fields such as altitude: number etc.).

These are however the only 2 fields of my interest, so I defined the type:

   coordinates: {latitude: number; longitude: number;};

Is this the correct way to define a type for a variable which would eventually have also other properties (e.g. latitude)? If not, what is the right way?

like image 469
dragonmnl Avatar asked Oct 20 '25 18:10

dragonmnl


1 Answers

Typescript checks the shape of types and can allow extra properties, so long as it can verify the required properties are present.

For example, you can define a type and function like:

type Coordinates = {latitude: number, longitude: number};

function logCoordinates(coords: Coordinates) {
  console.log('coordinates:', coords.latitude, coords.longitude);
}

and Typescript will happily accept any of these calls:

logCoordinates({latitude: 1, longitude: 2});

// assuming we have a CoordinateClass know to have lat and long
const coordinates = new CoordinateClass(1, 2); 
logCoordinates(coordinates);

The type annotation describes the shape of a contract. Any parameter that we can prove meets that contract is allowed. However, extra properties are not always allowed.

If you have extra properties and are passing an object literal -- class instances don't have this problem -- you may need to cast them into the desired type:

logCoordinates(<Coordinates>{latitude: 1, longitude: 2, altitude: 3});

You can solve that more robustly using an intersection type, as described here, which removes the need to cast by accepting any unmatched key:

type Coordinates = {latitude: number, longitude: number} & {[key: string]: number};
like image 195
ssube Avatar answered Oct 23 '25 06:10

ssube