[TS] - const in typescript

Truong Bui

Published on: Last updated:

ts

TABLE OF CONTENTS

  1. Problem
  2. Solution
  3. Why ?

Problem

type Brand = 'Mercedes' | 'Toyota' | 'Ferrari';

interface Car {
	speed: number;
	brand: Brand
}

function showCar(car: Car) { }

const mercedes = {
	speed: 500,
	brand: 'Mercedes'
}

showCar(mercedes)
//      ^^^^^^^^
// Argument of type '{ speed: number; brand: string; }'
// is not assignable to parameter of type 'Car'.
//   Types of property 'brand' are incompatible.
//    Type 'string' is not assignable to type 'Brand'.(2345)
Library: typescript v5.2.2

Solution

type Brand = 'Mercedes' | 'Toyota' | 'Ferrari';

interface Car {
	speed: number;
	brand: Brand
}

function showCar(car: Car) { }

const mercedes = {
	speed: 500,
- brand: 'Mercedes'
+ brand: 'Mercedes' as const
}

showCar(mercedes)
Library: typescript v5.2.2

Why ?

In typescript let or const has different behaviour
let brand = 'Mercedes';
//  ^^^^^ brand: string // primitive type
it's different when we use const
const brand = 'Mercedes';
	//  ^^^^^ brand: 'Mercedes' // literal type
But with object types, let and const are the same
let car = { brand: 'Mercedes' };
//  ^^^ car: { brand: string }
same with const
const car = { brand: 'Mercedes' };
//    ^^^ car: { brand: string }
So, that's the reason in the example at the top brand in Car interface is a literal type not string .
interface Car {
	speed: number;
	brand: Brand // branch is literal type, not a string
}
There are some order ways to solve this problem
// use type assertion
const mercedes = {
	speed: 500,
	brand: 'Mercedes'
} as Car

// use type annotation
const mercedes: Car = {
	speed: 500,
	brand: 'Mercedes'
}

// use const
const mercedes = {
	speed: 500,
	brand: 'Mercedes'
} as const
But my favorite solution is using as const directly on field because it's simple.
const mercedes = {
	speed: 500,
	brand: 'Mercedes' as const
}

Hope you find this article useful. If you have any questions, please let me know in the comment section below. 👇