angular - Typescript: referencia a interfaz en variable
Mientras implementaba el lado del cliente de una comunicación con el servidor, me encontré con el siguiente problema: ¿Cómo puedo almacenar una referencia a una interfaz en una variable?
Tengo una interfaz que contiene toda la información sobre una llamada específica a un backend RESTful:
export interface IEndpoint {
path: string,
method: HTTP_METHOD,
data: any,
response: any
}
Crear instancia de este elemento (ISomeInterface e IAnotherInterface son las interfaces a las que quiero referirme más adelante):
export const GET_TEST: IEndpoint = {
path: 'api/test',
method: HTTP_METHOD.GET,
data: <ISomeInterface>{},
response: <IAnotherInterface>{}
};
El objetivo es usar los campos de datos y respuesta como referencias de tipo en una Promesa (meta es una instancia de IEndpoint):
new Promise<meta.response>((resolve) => {
...
});
El tipo de callback de la Promise (meta.response) es donde no puedo extraer el tipo/interfaz que asigné previamente.
Respuesta #1
Los valores y los tipos existen en dos dominios diferentes. Los tipos se eliminan en tiempo de compilación, por lo que no podemos asignar un tipo a un campo de interfaz como intentas hacer.
Lo que podemos hacer es trabajar en el dominio de tipos y mantener los tipos data y response en el tipo IEndpoint usando parámetros genéricos, y extraerlos cuando sea necesario.
export interface IEndpoint<TData, TResponse> {
path: string,
method: HTTP_METHOD,
// just here because typescript doesn't handle unused generics well
_data?: TData,
_response?: TResponse
}
function makeRequest<T extends IEndpoint<any, any>>(endPoint: T, data: T['_data']): Promise<T['_response']> {
return null as any// actual call
}
interface ISomeInterface { data: string }
interface IAnotherInterface { result: string }
export const GET_TEST: IEndpoint<ISomeInterface, IAnotherInterface> = {
path: 'api/test',
method: "GET"
};
// Takes in ISomeInterface returns Promise<IAnotherInterface>
makeRequest(GET_TEST, { data: ""}).then(r=> r.result);
Como señala @jeroen-vervaeke, makeRequest también podría escribirse de una manera más simple con el mismo efecto:
function makeRequest2<TData, TResponse>(endPoint: IEndpoint<TData, TResponse>, data: TData): Promise<TResponse>{
return null as any;
}
Respuesta #2
Podrías solucionar tu problema con una clase genérica y enlazar el método a esta clase:
export class Endpoint<T, U> {
constructor(
private path: string,
private method: HTTP_METHOD,
private data: T,
private response: U
) {}
// your new promise method there
}
