I'm learning TypeScript and come across this use of index signatures in function parameters often. For eg,
export function template(resources: {[key: string]: any})
Since the value type is any, why is this type useful? And is it any different than passing object as the type?
CodePudding user response:
The object type is just a native js Object. It only has the functions and keys associated with the native Object.
So if you try to access a property of an object type, it will throw an error.
let b: object = {foo: 123};
b.foo; // Property 'foo' does not exist on type 'object'.(
But you can do the same with {[key: string]: any}
let a: {[key: string]: any} = {foo: 123};
a.foo;
You can do the same with Record<string, any>.
In fact, the Record type is declared as type Record<K extends string | number | symbol, T> = { [P in K]: T; }
CodePudding user response:
There are many ways to express 'objects', but consider the following examples. There is Object, object, {}, { [k: T]: U } and Record<K, T>. This is just because almost everything in JS (and by extension TS) is an object.*
I'll put the answer up-front with examples below:
Objectmeans any non-nullish valueobjectmeans any non-primitive value{}is the same asObject{ [k: string]: any }is equivalent toRecord<string, any>Record<K, T>is a utility type to create mapped types. Often used for as a substitute for index signatures withRecord<string, any>(shown above). Also can prescribe exact key/value pairs with something likeRecord<'foo' | 'bar', 'baz' | 'bang'>being equivalent to{ bar: "baz" | "bang"; foo: "baz" | "bang"; }- To type an empty object, it is recommended to use
Record<string, never> - To type any object, you should use
Record<string, unknown>orRecord<string, any> - To type any value, you should use
unknownorany
Examples
Consider the following about Object:
class C {}
const a: Object = 0
const b: Object = ""
const c: Object = []
const d: Object = {}
const e: Object = C
const f: Object = null // <-- error!
const g: Object = undefined // <-- error!
const h: Object = { foo: "bar" }
h.bar // Property 'foo' does not exist on type 'Object'.
Consider the following about object:
class C {}
const a: object = 0 // <-- error!
const b: object = "" // <-- error!
const c: object = []
const d: object = {}
const e: object = C
const f: object = undefined // <-- error!
const g: object = null // <-- error!
const h: object = { foo: "bar" }
h.bar // Property 'foo' does not exist on type 'object'.
Relevant Docs
Read about Record<K, T>.
Read about index signatures.
versus mapped types
