Reputation: 4098
I want to use an interface with generic union types like this:
interface IOperator {
<U>(a: U[], b: U[] | U): boolean
}
export const intersects: IOperator = (a, b) => a.some((el) => b.includes(el))
export const includes: IOperator = (a, b) => a.includes(b)
However, TS gives me error on both regarding one of the union types:
Property 'includes' does not exist on type 'U | U[]'.
Property 'includes' does not exist on type 'U'.
How do I typecast properly here?
I tried:
export const intersects: IOperator = (a, b) => a.some((el) => (b as U[]).includes(el))
However, that gives me an error:
Cannot find name 'U'.
So how to handle generic union types?
I know that for the intersects
method the types for input b
should only be arrays and for the includes
method the types for input b
should never be arrays. The idea for the interface is to not repeat myself as I have plenty of methods where some require b
to be an array and others to not be an array. I'd try to avoid to create two separate interfaces.
Thank you!
Upvotes: 0
Views: 736
Reputation: 15715
The issue with using casting here is if the value of B
doesn't match your casting, you'll have a runtime error. That being said, your use case may be valid and we just don't have the context available to see it. Otherwise, you may want to do a runtime check as suggested by some of the comments to your post.
This solution uses function
to give you access to U
, and then assigns the function to a const
so you can type check that your function signature matches your interface.
interface IOperator {
<U>(a: U[], b: U[] | U): boolean
}
function _intersects <U>(a: U[], b: U[] | U): boolean {
return a.some((el) => (b as U[]).includes(el));
}
export const intersects: IOperator = _intersects;
function _includes <U>(a: U[], b: U[] | U): boolean {
return a.includes(b as U);
}
export const includes: IOperator = _includes;
Upvotes: 1
Reputation: 247
I think:
export const intersects: IOperator = (a, b) => a.some((el) => Array.isArray(b)&&b.includes(el))
should work. Otherwise, b might not be an Array of type U, so that includes is not available.
Upvotes: 1