DEV Community

Taric Ov
Taric Ov

Posted on

Generics Hacks (1): ReadOnly in Typescript w/ 3 Examples

Image description

readonly is a keyword in TypeScript that we use when we want to make a property UNchangeable, so the value of the property cannot be changed after it has been set.

1) How to use the readonly keyword on a property of a type?


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

   const person1: Person = {
      name = "John";
      age: 30
  }
  // name property will not change 'cuz it was assigned to be readonly
  person1.name = "Sarah"; 
  person1.age = 20; 


Enter fullscreen mode Exit fullscreen mode

2) How to use the readonly keyword on an interface?


interface Car 
  make: string;
  model: string;
}

const readonlyCar1: Readonly<Car> = {
  make: "Tesla",
  model: "Model S"
};

// This will not compile because the make property is readonly
readonlyCar1.make = "Toyota"; 
// This will not compile because the model property is readonly
readonlyCar1.model = "Camry"; 
🟢
const car2: Car = {
  make: "Tesla",
  model: "Model S"
};

car2.make = "Toyota"; // OK ✅
car2.model = "Camry"; // OK ✅

Enter fullscreen mode Exit fullscreen mode

3) How to leverage generics and use the readonly keyword dynamically?

This is a normal static interface 👇


interface postProps {
  name: string;
  relativeTime: string;
  tweet: string;
  retweets: number;
  likes: number;
  comments: number;
  userImg: string;
  likedUsers: Array<{ name: string; img_src: string; id: number }>;
}

Enter fullscreen mode Exit fullscreen mode

Let's say now that we need to have a read-only version of this interface, now we have two scenarios:

  1. You already know the type: then you could do it manually 🤚 one by one putting thereadonlykeyword before each property.
  2. You don't know the type or you know it and it has tons of properties: then you use generics: 🤓

type readOnlyProps<T> = 
  readonly [K in keyof T]: T[K]; 
};
Enter fullscreen mode Exit fullscreen mode

What that means:

  • T is representing avariable for the type that you will use
  • K is representing the key of each property in theT type
  • you can think of it as an iterator that iterates over the passed types (postProps in this case)
  • e.g. first iteration: > Input 👉 readonly [name]: postProps[name]  > output 👉 readonly name: string;

Now you can create your new type and use it:


// your new type:
type readOnlyPostPorps = readOnlyProps<postProps>;

// you could use the new type now:
function Post(props: readOnlyPostPorps): JSX.Element {
  return (
    <>
      {...your JSX goes here}
    </>
  );
}
export default Post;

Enter fullscreen mode Exit fullscreen mode

Try this live example:

Any good in using Read-Only? looks like it does only one thing.

  1. Prevent bugs 🐞 by preventing developers from accidentally changing the value of a property.
  2. Improved maintainability 🔧 Code will become easier to maintain thanks to the first point (preventing bugs)
  3. Improved readability 👊 Code will become easier to read and understand by clearing out what can be changed and what cannot.

Top comments (0)