TypeScript Type Guards
A type guard combines a runtime test with a narrower view of a value. A user-defined predicate must test what it promises; TypeScript does not prove that your predicate is truthful.
How it works
A loose list may mix packet labels with missing entries and numbers. The predicate below accepts only non-empty strings. The annotation value is string lets filter produce a string array, while the actual checks supply runtime evidence. If you broaden the predicate later, revisit its type promise too. For object validation, inspect every property the narrowed type relies on, not merely the presence of one convenient field.
Run the code
Try in playground loads this source without running it. Choose Run when ready. The existing TypeScript 5.8.3 worker transpiles and executes one file; it does not perform full semantic type checking, load npm imports or provide DOM/Node APIs. Use the local compiler for the type contract.
For a full check, save the three downloads together in a new folder, run npm install, then npm run check. Use npm run build followed by npm start to execute the checked JavaScript with Node. The supplied project enables strict checking, indexed-access checks and exact optional properties.
Example
function isLabel(value: unknown): value is string {
return typeof value === "string" && value.trim().length > 0;
}
const incoming: unknown[] = ["Bean", null, 12, "", "Pea"];
const labels = incoming.filter(isLabel);
console.log(labels.map(label => label.toUpperCase()).join(", "));
Expected result
BEAN, PEA
filter calls the predicate for each item, then map can safely use a string method on accepted labels. The check rejects empty text but returns the original non-empty text, so trimming output would be a separate normalization step. Validation and normalization are related decisions, not interchangeable names for the same operation.