There are data types in TypeScript that are better known than others. Today I would like to introduce a less known data type: unknown
.
The unknown
data type
The unknown
type exists since TypeScript 3.0 (the current version is 4.2) and is a top type.
Similar to the any
type, a variable of type unknown
accepts values of any type.
The difference is that a value of type any
can be assigned to variables of all types and a value of type unknown
can only be assigned to variables of the type any
or unknown
.
/**
* New variable of type unknown
**/
let test: unknown;
/**
* Assigning a value to an unknown variable
**/
test = 'hello world'; // Works!
test = 5; // Works!
test = false; // Works!
test = () => false // Works!
test = new Audio(); // Works!
/**
* Using an unknown variable
**/
let myString: string = test; // Error: Type 'unknown' is not assignable to type 'string'
let myBool: boolean = test; // Error: Type 'unknown' is not assignable to type 'booelan'
const test2: unknown = test; // Works!
const test3: any = test; // Works!
test.foo(); // Error: Object is of type 'unknown'
new test(); // Error: Object is of type 'unknown'
When to use unknown
?
unknown
forces type checking and is safer than any
. That's why its use should always be favored over any
.
Here is an example with JSON.parse()
, which always returns a value of type any
.
In the following situation the code will compile without noticing that there is a huge error. The JSON string is not of type IPerson
and should not be assignable to the variable phoebe
.
interface IPerson {name: string, age: number}
const jsonString = '{"alias": "rose", "color": "red"}';
const person = JSON.parse(jsonString); // This returns any
const phoebe: IPerson = person; // This should throw a type error, but doesn't...
To make our code safer and catch the type error, we can use unknown
in combination with a custom Type Guard.
interface IPerson {name: string, age: number}
const jsonString = '{"name": "rose", "age": 25}';
const person: unknown = JSON.parse(jsonString); // This returns any.
const notPerson: IPerson = person; // Error Type 'unknown' is not assignable to type 'IPerson'.
/**
* Create a custom Type Guard to make sure that
* the parsed data is of type Person.
*/
const isPerson = (data: any): data is IPerson => {
return typeof data.name == 'string' && typeof data.age == 'number'
}
/**
* Use Type Guard.
*/
if(isPerson(person)){
console.log('This is a person!');
// With the Type Guard the assignement of the
// variable as type Person works.
const phoebe: IPerson = person;
} else {
throw Error('Parsed string is not a Person.')
}
Follow me on dev.to and twitter!
Top comments (0)