Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

159
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!