#How to exclude -1 from a type?
21 messages · Page 1 of 1 (latest)
Preview:```ts
function nullIfNegative<T extends number>(x: T): T | null {
return x >= 0 ? x : null;
}
// ---------------------
type T = 10 | 11 | 12;
declare const t: T | -1;
const value = nullIfNegative(t);
// The value of value is "T | -1 | null", but it should be "T | null"!
...```
function nullIfNegative<T extends number>(x: T | -1): T | null {
return x >= 0 ? x as T : null;
}
type T = 10 | 11 | 12;
declare const t: T | -1;
const value = nullIfNegative(t);
!ts value
const value: 10 | 11 | 12 | null /* 9:7 */```
alternatively Exclude<T, -1> in the return type
That doesn't work for e.g. -2 though, right?
oh right
Also, using Exclude<T, -1> doesn't make it compile anymore.
to clarify do you want to exclude all negative numbers, or just -1?
Well I'm curious as to the solution for both. Jakob's solution does seem to work great for the -1 case.
something like
type ExcludeNegativeNumber<T extends number> = `${T}` extends `-${number}` ? never : T;
hmm doesnt work distributively for some reason
this works type-wise:
Preview:```ts
type ExcludeNegativeNumbers<N extends number> =
N extends N
? ${N} extends -${string}
? never
: N
: never
function nullIfNegative<T extends number>(
x: T
): ExcludeNegativeNumbers<T> | null {
return x >= 0 ? x : null
}
// ---------------------
type T = 10 | 11 | 12
...```
ah perfect
so we just need to cast the return
that's very clever!
thank you mkantor, i'll have to remember that trick
yeah, template literal tricks for number operations are kinda fun, if hacky
it'd be nice to have more number/bigint literal operators at the type level, but until then i think this is the best you can do (well this and using tuple length to encode type-level natural numbers, which also feels hacky)