Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript '{}' type

Tags:

typescript

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:

  1. What is actually {} type in TypeScript? Does it really stands for "any non nullish value" (can't find confirmation in TypeScript documentation)?

  2. How should I actually type "empty object without any properties"?

like image 989
Furman Avatar asked Jun 15 '20 21:06

Furman


People also ask

Is type a keyword in TypeScript?

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.

How do you find TypeScript types?

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.

What is TypeScript symbol type?

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.


1 Answers

1. What is actually {} type in TypeScript? Does it really stand for "any non nullish value" (can't find confirmation in TypeScript documentation)?

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.

2. How should I actually type "empty object without any properties"?

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

Update #1

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.

Note:

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.

like image 123
Billy Cottrell Avatar answered Nov 11 '22 06:11

Billy Cottrell