How can you make typescript warn on an element level if that array element is present in another array?
For example:
const canBeAorB = <A1 extends ("a" | "b")[]>(arr: A1) => arr
const arr0 = canBeAorB(["b", "c"]) // Type '"c"' is not assignable to type '"a" | "b"'.
This is what I want to achieve for TS to warn me on a element that it is invalid
But instead of a value I need to guard against all elements of other array, for example:
const blockedElements = ["a", "b"]
const myArr = ["b", "c"] // make TS yell that "b" is invalid because its a member of blockedElements
I managed to get really close by doing this:
const blockedValues = ["a", "b"] as const;
type BlockedElement = typeof blockedValues[number];
const cannotHaveBlockedEls = <A1 extends Readonly<Exclude<A1[number], BlockedElement>[]>>(arr: A1) => arr
const arr3 = cannotHaveBlockedEls(["b", "c"] as const)
Which will yield:
Argument of type 'readonly ["b", "c"]' is not assignable to parameter of type 'readonly "c"[]'.
Type '"b" | "c"' is not assignable to type '"c"'.
Type '"b"' is not assignable to type '"c"'
But the error is displayed on top of the whole array argument instead of on top of "b", my real use case is a larger array where this would really make a difference.
Is it possible to do?