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"
CodePudding user response:
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.
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
CodePudding user response:
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.