I am looking for a type OddEvenArray<Odd,Even>
, which can do the following thing typesafe as OddEvenArray<string,number>
: ["a",1,"b",2]
.
I have no idea to distinguish between odd and even index during typing.
PS: I am sorry, but the JSON I am dealing with looks like that ^^'
CodePudding user response:
An array index is a number
type, and number types can either be any number (as number
) or specific numbers (as 1 | 2 | 47
).
There aren't really any other options at the type level. This means that something like this not possible to annotate as of Typescript 4.9.
CodePudding user response:
You cannot do that with Typescript. I wish you could. It would be a cool language feature.
The closest thing to an "even number" type would look something like the following. Wrap it in a class. Do the same thing with even numbers. Work out the kinks.
class EvenNumber {
public constructor(n: number) {
if (n % 2 != 0) {
throw new Error("argument is not even:", n);
}
this.num = n;
}
}
CodePudding user response:
this is only possible with function generic, you cannot directly assign this type to a variable, you must check with function
this only works for tuple, not array
type Odd<
X extends number,
Y extends unknown[] = [1],
Z extends number = never
> = Y['length'] extends X
? Z | Y['length']
: Odd<X, [1, 1, ...Y], Z | Y['length']>
type OddNumbers = Odd<1999> // 1 | 3 | 5 | 7 | ....1997
type IsStringAndOddTuple<T extends unknown[], ACC extends any[]=[]> =
T extends [infer A, ...infer J]
? T['length'] extends OddNumbers
? IsStringAndOddTuple<J,[...ACC, A extends number? A : "expect number type at even index" ]>
: IsStringAndOddTuple<J,[...ACC, A extends string? A : "expect string type at Odd index" ]>
:ACC
const isStringAndOddTuple =<T extends unknown[]>(tuple: T extends never? T : IsStringAndOddTuple<T>)=>{
// don't neeed anything here
}
type C = IsStringAndOddTuple<[1, 2, 3, 4]>
// ^?
type D = IsStringAndOddTuple<["a","b","c","d"]>
// ^?
type E = IsStringAndOddTuple<["a",1,"b",2]>
// ^?
isStringAndOddTuple([1, 2, 3, 4])
isStringAndOddTuple(["a","b","c","d"])
isStringAndOddTuple<["a",1,"b",2]>
reference:
Odd Number Type