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 )
	}
}