25747-hard-isnegativenumber

Back

type IsNegativeNumber<T extends number> =
  IfUnion<T, never, number> extends T
    ? never
  : `${T}` extends `-${string}`
    ? true
  : false

type IfUnion<T, UnionCase, NonUnionCase, U = T> = T extends any ? [U] extends [T] ? NonUnionCase : UnionCase : never

type _Number1 = Expect<Equal<number extends 0 ?       '✅' : '❌', '❌'>>
type _Number2 = Expect<Equal<number extends number ?  '✅' : '❌', '✅'>>
type _Number3 = Expect<Equal<number extends -1 | -1 ? '✅' : '❌', '❌'>>
type _Number4 = Expect<Equal<number extends -1 ?      '✅' : '❌', '❌'>>
type _Number5 = Expect<Equal<number extends never ?   '✅' : '❌', '❌'>>

type _Never1 = Expect<Equal<never extends 0 ?         '✅' : '❌', '✅'>>
type _Never2 = Expect<Equal<never extends number ?    '✅' : '❌', '✅'>>
type _Never3 = Expect<Equal<never extends -1 | -1 ?   '✅' : '❌', '✅'>>
type _Never4 = Expect<Equal<never extends -1 ?        '✅' : '❌', '✅'>>
type _Never5 = Expect<Equal<never extends never ?     '✅' : '❌', '✅'>>

Playground

Solution by teamchong #33055

type IsNegativeNumber<T extends number, C extends number = T> = number extends T
  ? never
  : T extends C
  ? [C] extends [T]
    ? `${T}` extends `-${infer N extends number}`
      ? true
      : false
    : never
  : never;

Solution by Vampirelee #32707

type IsNegativeNumber<T extends number, S extends number = T> =
  number extends S
    ? never
    : T extends T
      ? `${T}` extends `-${number}`
        ? [S] extends [T]
          ? true
          : never
        : false
      : never;

Solution by vangie #32251

type IsUnion<T, TT = T extends any ? T[] : never> = T[] extends TT ? false : true
type IsNegativeNumber<T extends number> = IsUnion<T> extends true
  ? never
  : number extends T
    ? never
    : `${T}` extends `-${number}`
      ? true
      : false

Solution by DevilTea #30926

type IsUnion<T, U = T> = U extends T ? [T] extends [U] ? false : true : never;

type IsNegativeNumber<T extends number> =
    number extends T ? never : 
      IsUnion<T> extends true ? never : 
        `${T}` extends `-${number}` ? true : false;

Solution by denysoblohin-okta #30428

// your answers
type MyEq<T, K> = (<Q>() => T extends Q ? 1 : 2) extends  (<Q>() => K extends Q ? 1 : 2) ? true : false

type TrueUnion<T, K = T> = T extends T ? MyEq<T, K> : never

type IsNegativeNumber<T extends number> = 
TrueUnion<T> extends false 
  ? never
  : T extends 0 
    ? false 
    : `${T}` extends `-${number}` ? true : number extends T ? never :false

Solution by 437204933 #29737

type IsNegative<T extends any> = T extends string
  ? T extends `-${infer Rest}`
    ? true
    : false
  : never;

Solution by slemchik03 #28558

type IsNegativeNumber<T extends number, U extends T = T> = 
  number extends T
    ? never
    : T extends U
      ? [U] extends [T]
        ? `${T}` extends `-${infer _}`
          ? true
          : false
        : never
      : never

Solution by jazelly #27809

type ToString<T extends number> = `${T}`;
type CheckIfNegative<T extends number> = ToString<T> extends `-${string}` 
  ? true
  : false;

type IsUnion<T, K = T> = T extends unknown 
  ? [K] extends [T] 
    ? false
    : true
  : never;

type IsNegativeNumber<T extends number> = number extends T
  ? never
  : IsUnion<T> extends true
    ? never
    : T extends 0
      ? false 
      : IsUnion<T> extends true
        ? never
        : CheckIfNegative<T>;

Solution by viktor-sakhno-saritasa #27672

type IsUnion<T, U = T> =
  [T] extends [never]
    ? false
    : T extends never
      ? false
      : [U] extends [T]
        ? false
        : true

type IsNegativeNumber<T extends number> =
  number extends T
    ? never
    : IsUnion<T> extends true
      ? never
      : `${T}` extends `-${infer _}`
        ? true
        : false

Solution by drylint #27436

type IsUnion<T, U = T> = T extends U
? [U] extends [T]
  ? false
  : true
: never

type IsNegativeNumber<T extends number> = number extends T
? never
: IsUnion<T> extends true
  ? never
  :`${T}` extends `-${number}`
    ? true
    : false

Solution by NeylonR #27093

type IsUnion<T, U extends T = T> =
  (T extends any ?
    (U extends T ? false : true)
    : never) extends false ? false : true

type IsNegativeNumber<T extends number> = IsUnion<T> extends true 
  ? never 
  : number extends T 
    ? never 
    : `${T}` extends `-${string}` 
      ? true 
      : false 

IS-UNION

Solution by Hfutsora #26851

type IsUnion<T, U = T> = T extends U ? ([U] extends [T] ? false : true) : never;

type IsNegativeNumber<T extends number> = number extends T
  ? never
  : IsUnion<T> extends true
  ? never
  : `${T}` extends `-${infer _}`
  ? true
  : false;

Solution by JohnLi1999 #26253

type IsUnion<T> = (() => T) extends (T extends any ? () => T : never) ? false : true
type IsNegativeNumber<T extends number> = number extends T
  ? never
  : IsUnion<T> extends true
    ? never
    : `${T}` extends `-${number}`
      ? true
      : false

Solution by XkSuperCool #26094

type IsUnion<T, U = T> = U extends T ? [T] extends [U] ? false : true : never;

type IsNegativeNumber<T extends number> = IsUnion<T> extends true ? never :   //union
  number extends T ? never :   //number
  `${T}` extends `-${number}` ? true : false;   //negative number

Solution by E-uler #26048

type IsUnion<T,U = T> = T extends U ?
  [U] extends [T]?false:true
  :never
type IsNegativeNumber<
  T extends number
> = 
IsUnion<T> extends true?
  never:
  number extends T?
    never:
    `${T}` extends `-${string}`?
      true:false

Solution by jiangshanmeta #25932