Reputation: 12860
I'm trying to conditionally return either KML or GeoJSON (string and object types respectively), and I'm wondering how to assign a function like that through an interface on an Object method.
Say the object is
const api = {
getGeometry(url, format) {
return fetch(`${url}?format=${format}`)
}
}
With an interface like this:
interface GeometryRequest {
(url: string, format: 'kml'): Promise<string>
(url: string, format: 'geojson'): Promise<GeoJSON.FeatureCollection<any>>
}
So I can get that to work as a plain function:
const geometryRequest: GeometryRequest = (url, format) => {
return fetch(`${url}?format=${format}`)
}
I'm just wondering how I can assign a type to an object method in a similar way.
Here are a couple of methods I tried:
getGeometry<GeometryRequest>
getGeometry: GeometryRequest
Neither are proper syntax.
I've also added a simpler version of the same problem on TypeScript Playground. In the playground output
's type is: const output: string | number
. But it should be able to tell the type from the overloaded functions in the interface somehow.
Any help on this syntax problem would be appreciated! :)
Upvotes: 1
Views: 510
Reputation: 249586
Function expressions can't specify multiple overloads. We can simulate the effect in one of several ways
Use a type assertion to specify the public signatures of the function
const a = {
b: function(c) {
if (typeof (c) === 'string') {
return parseInt(c)
}
return String(c)
} as {
(a: string): number
(a: number): string
}
}
Use conditional types to decide the return type based on the input type, although this will cause issues with the implementation when returning a value (the comp will not let you assign a value because it can't determine it to be safe)
const a = {
b<T extends string|number>(c : T ):T extends string ?number: string {
if (typeof (c) === 'string') {
return parseInt(c) as any
}
return String(c) as any
}
}
Use a function declaration inside a self executing function and return the declared function
const a = {
b: (function () {
function b(a: string): number
function b(a: number): string
function b(c) {
if (typeof (c) === 'string') {
return parseInt(c)
}
return String(c)
}
return b;
})()
}
Upvotes: 2