Posts > TS Basic: Narrowing

TS Basic: Narrowing

Narrowing refers to the process of refining the type of a variable or expression based on certain condition. It’s allow us to filter more specific assertions about the type of a value enabling better type checking.

πŸ‘ŒIn a nut shell this is a condition statement that compares the type of a variable incase of that variable has different kind

typeof type guard

using JS typeof operator to check the values type

πŸ‘Œit is useful for quickly distinguishing between different primitive type like string, number, boolean, undefined and null

function printValue(value: string | number){
	if( typeof value === 'string' {
		// value is narrowed to type string
	} else {
		// value is narrowed to type number
	}
}

Truthiness Narrowing

refers to a type narrowing that occurs when you use a truthy or falsy value in conitional statement.

πŸ‘Œfalse value includes: false , 0, null, NaN, undefined and empty string ''

function processValue(value: string | null){
	if(value){
		console.log(value.toUpperCase());
	}else{
		console.log('No value provided');
	}
}

Equality Narrowing

a type narrowing that occurs when you use equality or inequality operators to compare value.

type Shape = 
  | { kind: 'circle'; radius: number }
  | { kind: 'square'; sideLength: number };

function getArea(shape: Shape): number {
  if (shape.kind === 'circle') {
    // TypeScript knows that shape is of type { kind: 'circle'; radius: number }
    return Math.PI * shape.radius ** 2;
  } else {
    // TypeScript knows that shape is of type { kind: 'square'; sideLength: number }
    return shape.sideLength ** 2;
  }
}

const myCircle: Shape = { kind: 'circle', radius: 5 };
const mySquare: Shape = { kind: 'square', sideLength: 10 };

console.log(getArea(myCircle)); // Output: 78.53981633974483
console.log(getArea(mySquare)); // Output: 100

Custom type guard

you can also define your own type guards using type pedantic

πŸ‘Œcustom type guard allows you to define your own logic for narrowing based on your specific requirements. Especially useful when working with complex data structure

interface Square {
	kind: 'square',
	size: number,
}

interface Circle {
	kind: 'circle',
	radius: number,
}

type Shape = Square | Circle

function isSquare( shape: Shape ): shape is Square {
	return shape.kind === 'square'
}

function calculateArea( shape: Shape ) {
	if(isSquare(shape)){
		// square 
	}else {
		console.log('area of circle:', Math.PI + shape.radius * 5.1 )
	}
}

Tags 🏷