Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

161
Vistas
typescript: Array of templated interface extending multiple types

Here is a minimal example of my problem

interface Dog {
  legs: number;
}

interface Person {
  arms: number;
}

type Living = Person | Dog;

interface Speaker<T extends Living> {
  speak: (living: T) => void;
};

const michel: Speaker<Person> = { speak: (person) => console.log(`I have ${person.arms} arms`) };

const speakers: Array<Speaker<Living>> = [michel];

It throw this error

Type 'Speaker<Person>' is not assignable to type 'Speaker<Living>'.
  Type 'Living' is not assignable to type 'Person'.
    Property 'harms' is missing in type 'Dog' but required in type 'Person'

I would like to have an array of Speaker that accepts any type of Living.

Thanks for your time!

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

With the way you've defined things, Speaker<Living> means an object with a speak function that takes in a Person | Dog as its argument. When you create michel, you have the following function, which works fine if given a Person:

(person) => console.log(`I have ${person.arms} arms`)

But it would not work if given a Person | Dog, because it's trying to access the .arms property of a dog. That mismatch and others is why typescript is telling you that Speaker<Person> cannot be assigned to Speaker<Living>

If you want the array to be a mix of objects, some of which take Persons for their speak function, some of which take Dogs, then the type for that will be:

const speakers: Array<Speaker<Person> | Speaker<Dog>> = [michel];

EDIT: if your Living union is large, or you want speakers to update automatically when more types are added into Living, then you can use the following to get typescript to generate the Speaker<Person> | Speaker<Dog> union for you:

type Distribute<T> = T extends Living ? Speaker<T> : never;

const speakers: Array<Distribute<Living>> = [michel];
// speakers is of type Array<Speaker<Person> | Speaker<Dog>>

Playground link

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda