TypeScript接口索引器困惑:类型转换与函数签名差异疑问
Great question—let’s unpack these two points to clear up your confusion!
Why numeric indexers accept string keys
First, it’s critical to remember that TypeScript builds directly on JavaScript, and in JS, all object keys are actually strings (or Symbols). Even when you write obj[1], JavaScript silently converts the number 1 to the string "1" under the hood.
TypeScript’s numeric index signature ([noteId: number]: string[]) is designed to mirror this JS behavior while adding type safety. When you use a string like "1" to index into an object with a numeric indexer, TypeScript checks if that string can be safely converted to a number. Since "1" is a valid numeric string, it’s allowed—because at runtime, notes[1] and notes["1"] are exactly the same operation.
If you tried to use a string that can’t be converted to a number (like "abc"), TypeScript would throw a type error, as that doesn’t align with the intended numeric index pattern. The "conversion" happens conceptually during TypeScript’s type checking phase; the runtime conversion is handled natively by JavaScript itself.
Why use bracket indexers instead of function signatures?
These two constructs serve completely different purposes—they’re not interchangeable:
Bracket indexers define an object that acts like a dictionary or map. Your
Notesinterface with a numeric indexer describes an object where you can store multiple key-value pairs, e.g.:const notes: Notes = { 1: ["Grocery list"], 2: ["Meeting notes"] }; console.log(notes[1]); // Accesses the value for key 1 notes[3] = ["New note"]; // Adds a new key-value pairThis is for when you need to manage a collection of values that you can look up by key.
Function signatures define a function type. The interface
{ (noteId: number): string[] }describes a function that takes a number and returns a string array. You’d use it like this:const getNotes: Notes = (noteId) => { return [`Notes for ID ${noteId}`]; }; console.log(getNotes(1)); // Calls the function with argument 1 // getNotes[1] = ["..."]; ❌ This would throw an error—you can’t assign properties to this function (unless you explicitly extend the type)This is for when you need to define the shape of a function, not a collection of values.
In short: use indexers for dictionary-like objects, and function signatures for functions.
内容的提问来源于stack exchange,提问作者Julius Dzidzevičius

