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.
