What is TypeScript narrowing?

The admin panel that you'll actually want to use. Try for free.

October 27, 2023

In TypeScript, narrowing refers to refining the type of a variable so that TypeScript understands it to be more specific than its initial type. This guide walks you through the various methods of type narrowing available in TypeScript.

typeof type guards

One of the most basic ways to narrow a type in TypeScript is using the typeof operator. This is especially useful for distinguishing between primitive types.

let value: string | number; if (typeof value === 'string') { // value is narrowed to string here console.log(value.length); } else { // value is narrowed to number here console.log(value.toFixed(2)); }

instanceof type guards

When dealing with classes and object types, the instanceof operator helps in narrowing.

class Dog { bark() { console.log("Woof!"); } } class Cat { meow() { console.log("Meow!"); } } let pet: Dog | Cat; if (pet instanceof Dog) { pet.bark(); // TypeScript knows pet is of type Dog here } else { pet.meow(); // TypeScript knows pet is of type Cat here }

User-defined type guards

You can also define your own type guards using a function. The return type of this function should be a type predicate, parameterName is Type.

function isString(value: any): value is string { return typeof value === 'string'; } let item: string | number; if (isString(item)) { console.log(item.charAt(0)); // TypeScript knows item is string here } else { console.log(item.toFixed()); // TypeScript knows item is number here }

Literal type guards

When working with literal types, simple conditional checks can act as type guards.

type ButtonType = 'submit' | 'reset'; function handleClick(type: ButtonType) { if (type === 'submit') { // type is narrowed to 'submit' } else { // type is narrowed to 'reset' } }

You could ship faster.

Imagine the time you'd save if you never had to build another internal tool, write a SQL report, or manage another admin panel again. Basedash is built by internal tool builders, for internal tool builders. Our mission is to change the way developers work, so you can focus on building your product.

Non-null assertion

Sometimes, you might be certain that a value is non-null or non-undefined, even though TypeScript thinks otherwise. The non-null assertion operator ! can be used in such scenarios.

let foo: string | null = getSomeString(); // hypothetical function let bar: string = foo!; // we're asserting foo is not null

Discriminated unions

A powerful way of narrowing types in TypeScript is using discriminated unions. These involve creating objects with a common literal property that TypeScript can check to narrow down the type.

interface Circle { kind: 'circle'; radius: number; } interface Square { kind: 'square'; sideLength: number; } type Shape = Circle | Square; function getArea(shape: Shape): number { if (shape.kind === 'circle') { return Math.PI * shape.radius ** 2; } else { return shape.sideLength ** 2; } }

Using in operator

The in operator checks for the existence of a property in an object and can be used as a type guard.

type A = { foo: number }; type B = { bar: string }; function doSomething(value: A | B) { if ('foo' in value) { console.log(value.foo); // value is of type A here } else { console.log(value.bar); // value is of type B here } }

Using assert functions

Introduced in TypeScript 3.7, assertion functions allow you to define a function where the returned type is asserted to be a more specific type.

function assertIsString(val: any): asserts val is string { if (typeof val !== 'string') { throw new Error('Not a string!'); } } let data: any = fetchData(); // hypothetical function assertIsString(data); console.log(data.length); // TypeScript knows data is a string now

In conclusion, narrowing in TypeScript is a versatile tool to make the type system more expressive and safe. By leveraging the different techniques of narrowing, developers can write more robust and type-safe code.

TOC

typeof type guards
instanceof type guards
User-defined type guards
Literal type guards
Non-null assertion
Discriminated unions
Using in operator
Using assert functions

October 27, 2023

In TypeScript, narrowing refers to refining the type of a variable so that TypeScript understands it to be more specific than its initial type. This guide walks you through the various methods of type narrowing available in TypeScript.

typeof type guards

One of the most basic ways to narrow a type in TypeScript is using the typeof operator. This is especially useful for distinguishing between primitive types.

let value: string | number; if (typeof value === 'string') { // value is narrowed to string here console.log(value.length); } else { // value is narrowed to number here console.log(value.toFixed(2)); }

instanceof type guards

When dealing with classes and object types, the instanceof operator helps in narrowing.

class Dog { bark() { console.log("Woof!"); } } class Cat { meow() { console.log("Meow!"); } } let pet: Dog | Cat; if (pet instanceof Dog) { pet.bark(); // TypeScript knows pet is of type Dog here } else { pet.meow(); // TypeScript knows pet is of type Cat here }

User-defined type guards

You can also define your own type guards using a function. The return type of this function should be a type predicate, parameterName is Type.

function isString(value: any): value is string { return typeof value === 'string'; } let item: string | number; if (isString(item)) { console.log(item.charAt(0)); // TypeScript knows item is string here } else { console.log(item.toFixed()); // TypeScript knows item is number here }

Literal type guards

When working with literal types, simple conditional checks can act as type guards.

type ButtonType = 'submit' | 'reset'; function handleClick(type: ButtonType) { if (type === 'submit') { // type is narrowed to 'submit' } else { // type is narrowed to 'reset' } }

You could ship faster.

Imagine the time you'd save if you never had to build another internal tool, write a SQL report, or manage another admin panel again. Basedash is built by internal tool builders, for internal tool builders. Our mission is to change the way developers work, so you can focus on building your product.

Non-null assertion

Sometimes, you might be certain that a value is non-null or non-undefined, even though TypeScript thinks otherwise. The non-null assertion operator ! can be used in such scenarios.

let foo: string | null = getSomeString(); // hypothetical function let bar: string = foo!; // we're asserting foo is not null

Discriminated unions

A powerful way of narrowing types in TypeScript is using discriminated unions. These involve creating objects with a common literal property that TypeScript can check to narrow down the type.

interface Circle { kind: 'circle'; radius: number; } interface Square { kind: 'square'; sideLength: number; } type Shape = Circle | Square; function getArea(shape: Shape): number { if (shape.kind === 'circle') { return Math.PI * shape.radius ** 2; } else { return shape.sideLength ** 2; } }

Using in operator

The in operator checks for the existence of a property in an object and can be used as a type guard.

type A = { foo: number }; type B = { bar: string }; function doSomething(value: A | B) { if ('foo' in value) { console.log(value.foo); // value is of type A here } else { console.log(value.bar); // value is of type B here } }

Using assert functions

Introduced in TypeScript 3.7, assertion functions allow you to define a function where the returned type is asserted to be a more specific type.

function assertIsString(val: any): asserts val is string { if (typeof val !== 'string') { throw new Error('Not a string!'); } } let data: any = fetchData(); // hypothetical function assertIsString(data); console.log(data.length); // TypeScript knows data is a string now

In conclusion, narrowing in TypeScript is a versatile tool to make the type system more expressive and safe. By leveraging the different techniques of narrowing, developers can write more robust and type-safe code.

October 27, 2023

In TypeScript, narrowing refers to refining the type of a variable so that TypeScript understands it to be more specific than its initial type. This guide walks you through the various methods of type narrowing available in TypeScript.

typeof type guards

One of the most basic ways to narrow a type in TypeScript is using the typeof operator. This is especially useful for distinguishing between primitive types.

let value: string | number; if (typeof value === 'string') { // value is narrowed to string here console.log(value.length); } else { // value is narrowed to number here console.log(value.toFixed(2)); }

instanceof type guards

When dealing with classes and object types, the instanceof operator helps in narrowing.

class Dog { bark() { console.log("Woof!"); } } class Cat { meow() { console.log("Meow!"); } } let pet: Dog | Cat; if (pet instanceof Dog) { pet.bark(); // TypeScript knows pet is of type Dog here } else { pet.meow(); // TypeScript knows pet is of type Cat here }

User-defined type guards

You can also define your own type guards using a function. The return type of this function should be a type predicate, parameterName is Type.

function isString(value: any): value is string { return typeof value === 'string'; } let item: string | number; if (isString(item)) { console.log(item.charAt(0)); // TypeScript knows item is string here } else { console.log(item.toFixed()); // TypeScript knows item is number here }

Literal type guards

When working with literal types, simple conditional checks can act as type guards.

type ButtonType = 'submit' | 'reset'; function handleClick(type: ButtonType) { if (type === 'submit') { // type is narrowed to 'submit' } else { // type is narrowed to 'reset' } }

You could ship faster.

Imagine the time you'd save if you never had to build another internal tool, write a SQL report, or manage another admin panel again. Basedash is built by internal tool builders, for internal tool builders. Our mission is to change the way developers work, so you can focus on building your product.

Non-null assertion

Sometimes, you might be certain that a value is non-null or non-undefined, even though TypeScript thinks otherwise. The non-null assertion operator ! can be used in such scenarios.

let foo: string | null = getSomeString(); // hypothetical function let bar: string = foo!; // we're asserting foo is not null

Discriminated unions

A powerful way of narrowing types in TypeScript is using discriminated unions. These involve creating objects with a common literal property that TypeScript can check to narrow down the type.

interface Circle { kind: 'circle'; radius: number; } interface Square { kind: 'square'; sideLength: number; } type Shape = Circle | Square; function getArea(shape: Shape): number { if (shape.kind === 'circle') { return Math.PI * shape.radius ** 2; } else { return shape.sideLength ** 2; } }

Using in operator

The in operator checks for the existence of a property in an object and can be used as a type guard.

type A = { foo: number }; type B = { bar: string }; function doSomething(value: A | B) { if ('foo' in value) { console.log(value.foo); // value is of type A here } else { console.log(value.bar); // value is of type B here } }

Using assert functions

Introduced in TypeScript 3.7, assertion functions allow you to define a function where the returned type is asserted to be a more specific type.

function assertIsString(val: any): asserts val is string { if (typeof val !== 'string') { throw new Error('Not a string!'); } } let data: any = fetchData(); // hypothetical function assertIsString(data); console.log(data.length); // TypeScript knows data is a string now

In conclusion, narrowing in TypeScript is a versatile tool to make the type system more expressive and safe. By leveraging the different techniques of narrowing, developers can write more robust and type-safe code.

What is Basedash?

What is Basedash?

What is Basedash?

Ship faster, worry less with Basedash

Ship faster, worry less with Basedash

You're busy enough with product work to be weighed down building, maintaining, scoping and developing internal apps and admin panels. Forget all of that, and give your team the admin panel that you don't have to build. Launch in less time than it takes to run a standup.

You're busy enough with product work to be weighed down building, maintaining, scoping and developing internal apps and admin panels. Forget all of that, and give your team the admin panel that you don't have to build. Launch in less time than it takes to run a standup.

You're busy enough with product work to be weighed down building, maintaining, scoping and developing internal apps and admin panels. Forget all of that, and give your team the admin panel that you don't have to build. Launch in less time than it takes to run a standup.

Dashboards and charts

Edit data, create records, oversee how your product is running without the need to build or manage custom software.

USER CRM

ADMIN PANEL

SQL COMPOSER WITH AI

Screenshot of a users table in a database. The interface is very data-dense with information.