To gain further insights, consult the documentation on user-defined type guard functions.
function determineString(input: any): input is string{
return typeof input === "string";
}
function demonstrateExample(value: any){
if(determineString(value)){
console.log("This is a string: " + value);
console.log(value.length); // string function
}
}
demonstrateExample("hello world");
In the scenario depicted above, utilizing the type predicate input is string
(rather than just returning
boolean</code), subsequent to calling <code>determineString()
, if the outcome is true,
TypeScript will narrow down the type to string
within any section safeguarded by invoking the function.
The compiler will infer that
value
pertains to
string
in the enclosed guarded block (solely within the surrounded guarded block)
{
console.log("This is a string: " + value);
console.log(value.length); // string function
}
A type predicate is strictly used during compilation phase. The resultant .js
file (during runtime) will exhibit no variance since it doesn't contemplate the TYPE.
The distinctions between the following four instances will be illustrated.
For instance 1:
the provided code example won't trigger either a compile or runtime error.
For instance 2:
the subsequent code snippet will generate a compilation error (as well as a runtime error) because TypeScript has narrowed down the type to string
and verified that toExponential
isn't contained within string
method.
function demonstrateExample(value: any){
if(determineString(value)){
console.log("This is a string: " + value);
console.log(value.length);
console.log(value.toExponential(2));
}
}
For instance 3:
the ensuing code excerpt won't trigger a compile error but will encounter a runtime error as TypeScript solely narrows down the type to string
in the guarded block, not post-guard, therefore, value.toExponential
won't yield a compile error (TypeScript doesn't recognize it as a string
type). However, during runtime, string
lacks the toExponential
method, hence leading to a runtime error.
function demonstrateExample(value: any){
if(determineString(value)){
console.log("This is a string: " + value);
console.log(value.length);
}
console.log(value.toExponential(2));
}
For instance 4:
if we exclude input is string
(type predicate), TypeScript won't narrow down the type in the guarded block, and the following code snippet won't raise a compile error but it will incur a runtime error.
function determineString(input: any): boolean{
return typeof input === "string";
}
function demonstrateExample(value: any){
if(determineString(value)){
console.log("This is a string: " + value);
console.log(value.length);
console.log(value.toExponential(2));
}
}
Hence, employing input is string
(type predicate) aids developers foresee potential runtime errors during compile time. With JavaScript, developers are unaware of these errors during compilation. This constitutes the advantage of leveraging TypeScript.