I have a simple interface:
interface Animal<T> {
isMatch: (value: T) => boolean
}
with these implementations:
class Dog implements Animal<string> {
isMatch(input: string): boolean {
// do something with string
}
}
and
class Cat<T extends T[]> implements Animal<T> {
isMatch(input: T[]): boolean {
// do something with list
}
}
I can instantiate a Dog
without issue with:
const dog = new Dog("pug")
However, I can't instantiate a Cat
with any of:
const siamese = new Cat<string>(...) // Type 'string' does not satisfy the constraint 'string[]'
const persian = new Cat<string[]>(...) // Type 'string[]' does not satisfy the constraint 'string[][]'
const sphynx = new Cat(["birman"]) // Type 'string' does not satisfy the constraint 'string[]'
I've used the generics / extends based on examples I've seen online, so not sure what I'm misunderstanding here.
CodePudding user response:
I understand why you used T extends T[]
, because of this error when you don't:
Type 'T' is not assignable to type 'T[]'.(2416)
input.tsx(11, 11): This type parameter might need an
extends T[]
constraint.
This error is misleading in this case, but if we think through what we want, we can get the solution.
You want isMatch
to take the type T[]
. However, Cat
only takes T
. Remember that isMatch
is defined by the interface Animal
, and in the interface, it takes T
(in the interface). If we want these types to match, we just have to make Animal
take T[]
!
class Cat<T> implements Animal<T[]> {
And that's it.