=" /> =" /> ="/>

TypeScript Utility Types use case

68 Views Asked by At
type Product = {
  name: string;
  price: number;
}

// Utility Type A
type Keys<T> = keyof T & string;

// Utility Type A without "& string"
type Keys<T> = keyof T & string;

type KeysOfProduct = Keys<Product>

Given the above condition, what are the differences when we use Utility Type A or Utility Type A without "& string"

2

There are 2 best solutions below

0
Nicholas Tower On BEST ANSWER

The & string is used to eliminate any keys of the object which are not strings. In other words, it gets rid of numbers and symbols. Your Product type doesn't have any of these, but different objects might.

For example:

const foo = Symbol();

type Product = {
  name: string;
  price: number;
  [3]: boolean;
  [foo]: string;
}

type KeysWithoutString<T> = keyof T;
type KeysWithString<T> = keyof T & string

const example1: KeysWithoutString<Product> = 'name';
const example2: KeysWithoutString<Product> = 'price';
const example3: KeysWithoutString<Product> = 'error'; // Error (not a key)
const example4: KeysWithoutString<Product> = 3; // Allow
const example5: KeysWithoutString<Product> = foo; // Allowed

const example6: KeysWithString<Product> = 'name';
const example7: KeysWithString<Product> = 'price';
const example8: KeysWithString<Product> = 'error'; // Error (not a key)
const example9: KeysWithString<Product> = 3; // Error (a key, but not a string)
const example10: KeysWithString<Product> = foo; // Error (a key, but not a string)

Playground Link

0
adsy On

Nothing. The & string in this case results in an effectual no-op. Since the keys of Product are string literals (name, price), intersecting the general string type with them just results in a type representing the string literals name and price still.

If you wanted to allow loose strings as well as the strongly typed ones you would do keyof T | string instead.