Type narrowing restricts a union-typed expression to a more specific type so TypeScript permits the properties and methods associated with that type. Assertions use the as keyword to select a type, while guards such as instanceof or property checks narrow values during control flow. section 7.4 section 11.2
Use narrowing to work safely with values that may have different shapes:
- Assert a known result type with calculateTax(100, false) as number, then call number methods such as toFixed. section 7.4
- Use instanceof when TypeScript understands class instances, allowing Employee methods after the check. section 11.3
- Check for a distinguishing property, such as "dept" in item, when constructor-function objects cannot be narrowed with instanceof. section 11.2
- Narrow a union returned by a generic collection before using type-specific behavior, as with a Person | Product result. section 12.2.1
Narrowing a mixed collection
type dataType = Person | Product; let peopleData = new DataCollection(people); let firstPerson = peopleData.getItem(0); if (firstPerson instanceof Person) { console.log(`First Person: ${firstPerson.name}, ${firstPerson.city}`); } The collection can return either union member, so the instanceof check establishes Person before accessing Person-specific behavior. section 12.2.1
Listing 7.23 Using type assertions in the index.ts file in the src folder
function calculateTax(amount: number, format: boolean): string | number {
const calcAmount = amount * 1.2;
return format ? `$${calcAmount.toFixed(2)}` : calcAmount;
}
let taxNumber = calculateTax(100, false) as number;
let taxString = calculateTax(100, true) as string;
console.log(`Number Value: ${taxNumber.toFixed(2)}`);
console.log(`String Value: ${taxString.charAt(0)}`);
See the complete assertion example, including the union-returning function, as expressions, method calls, and runtime output. section 7.4
