Question about TypeScript {}
type - up to this point I thought it means "empty object with no properties" type, but recently I stumbled upon eslint rule which forbids using {}
type because means "any non nullish value". Quick test in typescript playground says it's true:
let d: {} = {};
d = false;
This code doesn't give compiler error, but when I try to assign null
to d, indeed there is an error. So my questions are:
What is actually {}
type in TypeScript? Does it really stands for "any non nullish value" (can't find confirmation in TypeScript documentation)?
How should I actually type "empty object without any properties"?
The type keyword in TypeScript is a way for you to provide type aliases to your variables, objects, and functions. These aliases essentially describe what your data is going to look like.
In Typescript, we have three ways to work with it using: typeof: the keyword helps to check values types, like boolean, string, number, etc. instanceof: the keyword to compare the object instance with a class constructor. type guards: The powerful way to check types using typescript feature language.
In Typescript symbol is a primitive data type. A primitive data type is not an object, it possesses no properties or methods and they cannot be altered. The symbol type is similar to other types such as number, string, boolean, etc. Symbol values are created using the Symbol constructor.
If you do console.log(typeof(d));
then you will see that {}
is of type object
. Except this is not entirely correct but let me explain about object first. First of all object
with lowercase o
can be any non-primitive value while Object
with uppercase O
can include any primitive value through Object.prototype
.
So if you try to overwrite object with a primitive value it will give errors as it doesn't like primitive values, although null will work as is a object
type aswell, undefined on the other hand is of type undefined but this can always be assigned.
Now {}
is called "Object literal" this is actually both object
and Object
. So that is why both primitive and non-primitive values are assignable to an object literal as mentioned on packt.
So normally any value can be assigned to an object literal.
You can check this in the following stackblitz.
There are probably a couple of ways to do this, the ones I know are you can either instantiate it like you did or do: let d = {};
as the type is automatically determined there is no need to add a type.
The other method is to use an interface to define your properties when they are known but make them all optional by adding question marks behind the property names. This makes it easy to use aswell since all your properties are known and can be found by intellisense aswell.
Example:
export interface User {
name?: string;
email?: string;
}
let user: User = {};
user.name = "Joe";
user.email = "[email protected]";
If this didn't answer your question sufficiently, feel free to ask away!
Ps: for more information on objects check out 2ality
As Paddokt mentioned in the comments if you want to type an object either as an empty object or only a specific object the above example won't work so to do this a different approach is required.
If you want the example above to be only either a User or an empty object you would have to wrap the user object inside a different object as following:
export interface optUser {
user?: User;
}
export interface User {
name: string;
email: string;
}
let optuser: optUser = {};
optuser.user = {
name: "Joe",
email: "[email protected]"
}
This way you can have a variable that is either an empty object or an object that contains a user where both name and email are required.
Do know that optuser.user = {};
won't work, either optuser has a user object or it doesn't have an object at all, as User itself can't be an empty object here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With