Búsqueda de sitios web

¿Cómo puedo especificar un literal de objeto tipado en TypeScript?


¿Hay una manera de crear un literal de objeto tipado directamente?

Por directamente me refiero a sin tener que asignarlo a una variable que tenga anotación de tipo.

Por ejemplo, sé que puedo hacerlo así:

export interface BaseInfo { value: number; }

export interface MyInfo extends BaseInfo { name: string; }

function testA(): BaseInfo = {
   const result: MyInfo = { value: 1, name: 'Hey!' };
   return result;
}

También puedo hacerlo así:

function testB(): BaseInfo = {
   return { value: 1, name: 'Hey!' };
}

Pero lo que necesito es algo como:

function testC(): BaseInfo = {
   return { value: 1, name: 'Hey!' }: MyInfo; // <--- doesn't work
}

O así:

function testD(): BaseInfo = {
   return MyInfo: { value: 1, name: 'Hey!' }; // <--- doesn't work
}

Respuesta #1

RESPUESTA ORIGINAL es usar la función identidad:

function to<T>(value: T): T { return value; }
const instance = to<MyInfo>({
    value: 1,
    name: 'Hey!',
});

no debería haber ningún impacto en el rendimiento por una llamada innecesaria a la función to, debería ser optimizada por el compilador JIT

RESPUESTA ACTUALIZADA el 22 de septiembre de 2022:

Finalmente, el equipo de TypeScript hizo una herramienta para esto:

const instance = { value: 1, name: 'Hey!' } satisfies MyInfo;

Leer más: https://github.com/microsoft/TypeScript/issues/47920

Algunas capturas de pantalla:

Respuesta #2

Intellisense para los miembros de literales de objeto es proporcionado por el tipo contextual (ver sección 4.19 de la especificación) de la expresión.

Puede adquirir un tipo contextual de diversas maneras. Algunos de los lugares más comunes donde se aplica un tipo contextual son:

  • El inicializador de una variable con una anotación de tipo
  • La expresión en una declaración return en una función o getter con una anotación de tipo de retorno
  • La expresión en una expresión de aserción de tipo (<T>expr)

En tu ejemplo, puedes usar una aserción de tipo para forzar a que tu literal de objeto tenga un tipo contextual:

function testB() {
   return <IMyInfo>{ name: 'Hey!' };
}

Artículos relacionados