Reusable union narrowing
A union contains object variants that can be distinguished by a property or shape check.
TypeScript · Const
The is keyword forms a type predicate in a function return type. It connects a runtime check to control-flow narrowing, letting TypeScript treat a compatible parameter as a specific type when the function returns true.
The is syntax declares a type predicate in a function return type. When the function returns true, TypeScript narrows the named parameter to the stated type, provided the original value is compatible; the predicate itself still needs a runtime check that correctly reflects the claim.
function predicate(parameter: Input): parameter is Target {
return check(parameter);
}| Name | Type | Description |
|---|---|---|
parameterName | the parameter's declared type | The function parameter whose runtime value is checked and narrowed. |
A boolean result whose true branch narrows the named parameter to the predicate's Type.
is and the narrowed target type after it.this is Type to narrow the receiver.is must refer to a parameter declared by that function.type Fish = { swim: () => void };
type Bird = { fly: () => void };
function isFish(pet: Fish | Bird): pet is Fish {
return "swim" in pet;
}
function move(pet: Fish | Bird) {
if (isFish(pet)) pet.swim();
else pet.fly();
}
move({ swim() {} });The predicate function checks a runtime property and lets TypeScript narrow the union inside the corresponding branch.
A union contains object variants that can be distinguished by a property or shape check.
A codebase needs one domain-specific runtime check shared across branches and modules.
A class method establishes a more specific state or capability for its instance.
value is T mean?A type predicate has the form parameterName is Type in a function return type. When the function returns true, TypeScript narrows the argument to that type if the original type is compatible.
Follow-up: Can a predicate narrow a class instance through this is Type? Yes; classes can use that form to narrow their own type.
The predicate names a function parameter, while the function body performs the runtime test. This combines JavaScript checks such as property presence with compile-time control-flow narrowing.
Follow-up: What happens when the function returns false? In the documented inferred-predicate rules, false means the value does not have the predicate type, so the check must have if-and-only-if behavior.
A predicate is useful when a union needs a reusable, domain-specific check that built-in guards cannot express. For example, checking whether swim exists can distinguish Fish from Bird before property access.
Follow-up: What is a safer alternative for new designs? Prefer discriminated unions when possible, because a shared discriminant makes runtime narrowing more direct.
type guardtype predicatenarrowingthis is Type