#How to exclude -1 from a type?

21 messages · Page 1 of 1 (latest)

hybrid charm
#

Consider the following tiny playground:
[edit - see bot link below]

gloomy elkBOT
#
zamiel#0

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"!
...```

late frost
#
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

gloomy elkBOT
#
const value: 10 | 11 | 12 | null /* 9:7 */```
late frost
#

alternatively Exclude<T, -1> in the return type

hybrid charm
late frost
#

oh right

hybrid charm
#

Also, using Exclude<T, -1> doesn't make it compile anymore.

abstract anchor
#

to clarify do you want to exclude all negative numbers, or just -1?

hybrid charm
#

Well I'm curious as to the solution for both. Jakob's solution does seem to work great for the -1 case.

late frost
#

something like

type ExcludeNegativeNumber<T extends number> = `${T}` extends `-${number}` ? never : T;
#

hmm doesnt work distributively for some reason

gloomy elkBOT
#
mkantor#0

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
...```

hybrid charm
#

ah perfect

#

so we just need to cast the return

#

that's very clever!

#

thank you mkantor, i'll have to remember that trick

abstract anchor
#

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)