Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

229
Visualizações
Narrowing down to common JS methods and properties in TypeScript

Is there a way to make this TypeScript narrowing less ugly (or more elegant ;-) ❓

With IsSomething type guard, I want to narrow down access to common methods and properties of any JavaScript variable which is not null and not undefined (things like .toString, .valueOf, .hasOwnProperty, .constructor etc.)

Playground link

export type Something = 
  number | string | boolean | symbol | object | bigint;

export function IsSomething(value: unknown) : value is Something {
  return value !== undefined && value !== null;
}

let a = [1, "2", 3];
Narrowing(a);
NotNarrowing(a);

function Narrowing(o: unknown) { // OK
    if (IsSomething(o)) {
      console.log(o.toString(), o.constructor);
    }
}

function NotNarrowing(o: unknown) { // NOT OK
    if (o !== null && o !== undefined) {
      console.log(o.toString(), o.constructor);
    }
}
about 4 years ago · Santiago Gelvez
2 Respostas
Responde à pergunta

0

In TypeScript, every value except for null and undefined is assignable to the so-called empty object type {}. So you can simplify your Something to just {} and your user-defined type guard function will work the same as before:

export type Something = {};
function isSomething(value: unknown): value is Something {
  return value !== undefined && value !== null;
}
function narrowing(o: unknown) { // OK
  if (isSomething(o)) {
    console.log(o.toString(), o.constructor);
  }
}

Furthermore, TypeScript 4.8 will introduce improved support for narrowing unknown, after which your "NotNarrowing" function will start working, because checking (o !== null && o !== undefined) will narrow o from unknown to {} automatically:

// TS4.8+ 
function nowNarrowing(o: unknown) { // okay
  if (o !== null && o !== undefined) {
    console.log(o.toString(), o.constructor);
  }
}

Playground link to code

about 4 years ago · Santiago Gelvez Relatório

0

@jcalz's excellent answer led me to the following solution:

// With `IsSomething` type guard, I want to narrow down access 
// to common properties of any JS variable 
// which is not null and not undefined, like: 
// .toString, .valueOf, .hasOwnProperty, .constructor etc.

export function IsSomething(value: unknown) : value is Object {  
  return value !== null && value !== undefined;
}

Narrowing([1, 2, 3]);

function Narrowing(o: unknown) { // OK
    if (IsSomething(o)) {
      console.log(o.toString(), o.constructor);
    }
}

It turns out, TypeScript has a predefined interface Object, which works exactly the way I want:

Object interface in TypeScript

In TypeScript, the Object interface is different from the primitive object type, as the former is still assignable to any other primitive or complex type. It is also different from an empty type like type Something = {}, as the latter doesn't supports IntelliSense.

// Object interface is OK
let a: Object = 42; 
let b: Object = true;
let c: Object = "string";
let d: Object = Symbol(42);
let e: Object = new class SomeClass { someProp = 42 };

// Empty type is OK but no IntelliSense 
let a1: {} = 42; 

// Error: Type 'number' is not assignable to type 'object'
let a2: object = 42; 

Playground link.

One subtle issue still remains. As @CertainPerformance pointed out, the above won't work for an edge case like Object.create(null), where an object is created which doesn't have any properties or methods, but isn't null either.

If that's a requirement, the following should do the job:

// can be extended to check for toString, valueOf, etc
export function IsSomething(value: unknown) : value is Object {
  return (<Object>value)?.constructor !== undefined;
}

Narrowing([1, 2, 3]);

function Narrowing(o: unknown) { // OK
  if (IsSomething(o)) {
    console.log(o.toString(), o.constructor);
  }
}
about 4 years ago · Santiago Gelvez Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda