Strict Object Literal Checking (Freshness) in TypeScript

Strict Object Literal Checking, also known as “Freshness checking” in TypeScript, is a feature that helps ensure the accuracy and reliability of your code when working with objects. It helps you catch errors related to incorrect property assignments when creating objects.

Here’s an explanation:

What is Freshness Checking?

Imagine you have a TypeScript program, and you want to create an object with specific properties, such as a person’s name and age. Freshness checking makes sure that you can only assign the properties you initially specified, nothing more, nothing less. This prevents accidental mistakes in your code.

How to Use Freshness Checking:

Enable Strict Mode: You need to enable TypeScript’s strict mode. It’s like setting your TypeScript to be extra cautious. you can enable specific strict options individually in your tsconfig.json file.

{
"compilerOptions": {
"strict": true
}
}

Define Your Object Type: You define what your object should look like using TypeScript’s type system. For example, you might say a person object should have a name (a string) and an age (a number).

Create an Object Literal: When you create an object literal (a new object with curly braces {}), TypeScript checks that you only add properties that match the type you defined earlier.

Example:

Let’s say you want to create a person object. You define its type like this:

type Person = {
name: string;
age: number;
};

Now, when you create a person object, you must follow these rules:

const validPerson = { name: "John", age: 30 }; // This is correct.

const invalidPerson = { name: "Jane", age: 25, gender: "Female" }; // This is incorrect.

In the first example, you create a validPerson with only the name and age properties, which matches the Person type. This is correct, and TypeScript is happy.

In the second example, you try to create an invalidPerson with an extra property gender. TypeScript detects this and tells you it’s incorrect because the Person type only allows name and age.

We have describe some more example with topic wise.

  1. Readonly Properties:

In TypeScript, you can also use the readonly modifier to make object properties immutable. This ensures that once a property is assigned a value, it cannot be changed later. This can be especially useful in combination with Freshness Checking to create objects that are meant to be constant.

type Point = {
readonly x: number;
readonly y: number;
};

const origin: Point = { x: 0, y: 0 };
origin.x = 10; // Error: Cannot assign to 'x' because it is a read-only property.
  1.  Index Signatures:

If you have an object type with unknown or dynamic property names, you can use an index signature to allow any property name of a certain type. Freshness Checking will still work, but you can access properties with any name that matches the index signature.

type Dictionary = {
[key: string]: number;
};

const myDict: Dictionary = {
one: 1,
two: 2,
};

myDict.three = 3; // This is allowed because of the index signature.
myDict.four = "four"; // Error: Type '"four"' is not assignable to type 'number'.

In this example, properties with any string name can be added to myDict, but TypeScript still checks the types of values assigned to those properties.

  1. The as const Assertion:

You can use the as const assertion to tell TypeScript that an object should have literal types for all its properties. This can be helpful in scenarios where you want to ensure that object properties are constants.

const config = {
theme: "dark",
fontSize: 16,
} as const;

config.theme = "light"; // Error: Cannot assign to 'theme' because it is a read-only property.
config.fontSize = 14; // Error: Cannot assign to 'fontSize' because it is a read-only property.

In this example, the as const assertion ensures that the properties of config are treated as read-only literals.

  1. The Partial Utility Type:

Sometimes, you may want to create an object where only some properties are required, and the others are optional. TypeScript provides the Partial utility type for this purpose.

type Person = {
name: string;
age: number;
address?: string;
};

const partialPerson: Partial<Person> = {
name: "John",
};

Here, Partial<Person> allows you to create an object with some or all properties from the Person type.

Freshness checking helps prevent these types of errors at the very beginning, during code development, so you can catch and fix them before your code runs. It ensures that your objects follow the rules you set, making your TypeScript code more reliable and less error-prone.

 

Leave a Reply

Your email address will not be published. Required fields are marked *