Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: Property 'length' does not exist on type 'never'

Tags:

typescript

I have a set of basic function:

export function isObject(value: any): value is Object {
  return value !== null && typeof value === 'object' && !isArray(value);
}

export function isNumber(value: any): value is number {
  return typeof value === 'number' && !isNaN(value);
}

export function isString(value: any): value is string {
  return typeof value === 'string';
}

export function isArray(value: any): value is Array<any> {
  return Array.isArray(value);
}

export function isNull(value: any): value is null {
  return value === null;
}

export function isUndefined(value: any): value is undefined {
  return value === undefined;
}

export function isNullOrUndefined(value: any): value is null | undefined {
  if (isNull(value) || isUndefined(value)) {
    return true;
  }
  return false;
}

and a "special function" that check if a value is null, undefined or empty (empty string, 0 for number, empty array or empty object {}):

export function isNullOrUndefinedOrEmpty(value: any): value is null | undefined | '' | [] | {} | 0 {
  if (isNullOrUndefined(value)) {
    return true;
  }
  if (isString(value)) {
    return value === '';
  }
  if (isNumber(value)) {
    return value === 0;
  }
  if (typeof value === 'number' && isNaN(value)) {
    return true;
  }
  if (isArray(value)) {
    return value.length <= 0;
  }
  if (isObject(value)) {
    return Object.keys(value).length === 0 && value.constructor === Object;
  }
  return false;
}

when i use isNullOrUndefinedOrEmpty() typescript show the error:

Property 'length' does not exist on type 'never', example:

export function foo(myArray: Array<any>): Array<any> {
  if (isNullOrUndefinedOrEmpty(myArray)) {
    return myArray;
  }
  // on myArray: Property 'length' does not exist on type 'never'
  for (let i = 0, e = myArray.length; i < e; i++) {
    // ... some logic
  }
  return myArray;
}

what i'm doing wrong?

online demo

like image 683
ar099968 Avatar asked Nov 14 '25 23:11

ar099968


1 Answers

In TypeScript, { foo: any; bar: any } means "any value that has at least properties foo and bar". Notably, values with more properties will also fit that type.

It follows, then, that {} means "any value that has at least nothing". Since all values have at least nothing in them (even null and undefined), they will all fit the type. So after eliminating {} there is only the impossible case (never) left.

I don't know of a way to express "empty objects only" in TypeScript. But if you only call that function with arrays, then this signature can work instead:

function isNullOrUndefinedOrEmpty(x: any[]): x is null | undefined | [] {
like image 89
Lambda Fairy Avatar answered Nov 17 '25 18:11

Lambda Fairy