Reputation: 9938
i'm trying to make a definition for docuri
export type URI<K extends RouteParams> = string;
export interface RouteParams {
[key: string]: (string | number | boolean)
}
export interface Document {
[key: string]: (string | number | boolean)
}
/**
* Create a URI from a document properties
* @param the props to build the URI from
* @return the URI
*/
export type RouteCreator<K extends RouteParams> = (props: K) => string;
/**
* Parses a URI and returns the props
* @param uri the URI to parse
* @return the params parsed from URI
*/
export type RouteParser<K extends RouteParams> = (uri: string) => K;
export type Route<T extends RouteParams> = RouteParser<T> | RouteCreator<T>;
/**
* Creates a Route which is a function that either parse or stringify object/string
* @param route the route uri
* @return the Route
*/
export type RouteFactory<K extends RouteParams> = (route: string) => Route<K>;
export interface DocURI<K extends RouteParams> {
route: RouteFactory<K>;
}
And then to use it:
import {DocURI, Document, RouteParams, URI, RouteFactory} from './Definitions';
const docuri = require('docuri');
function getRoute <T extends Document> (): DocURI<T> {
return (docuri as DocURI<T>);
}
...
const artistURI = getRoute<ArtistParams>().route('artist/name');
const parsed = artistURI(album.artist); // Cannot invoke an expression whose type lacks a call signature. Type 'Route<ArtistParams>' has no compatible call signatures.
And I get on the last line:
Cannot invoke an expression whose type lacks a call signature. Type 'Route<ArtistParams>' has no compatible call signatures.
What am I doing wrong?
Upvotes: 1
Views: 7989
Reputation: 164137
Check out this issue: Call signatures of union types:
This is currently by design because we don't synthesize an intersectional call signature when getting the members of a union type -- only call signatures which are identical appear on the unioned type
So for now you'll need to either make both of the function signatures the same, or cast the result:
const artistURI = getRoute<ArtistParams>().route('artist/name') as (str: string) => string;
const parsed = artistURI(album.artist); // should be ok
Upvotes: 3