question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`Type 'string' cannot be used to index type 'T'` when indexing a generic function parameter

See original GitHub issue

Bug Report

🔎 Search Terms

Type ‘string’ cannot be used to index type ‘T’.

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about index signature

⏯ Playground Link

Playground link with relevant code

💻 Code

function foo<T extends Record<string | symbol, any>>(target: T, p: string | symbol) {
  target[p]; // This is okay
  target[p] = ""; // This errors
}

🙁 Actual behavior

(parameter) target: T extends Record<string | symbol, any>
Type 'string' cannot be used to index type 'T'.(2536)
Type 'symbol' cannot be used to index type 'T'.(2536)

🙂 Expected behavior

Either:

  1. It should work, as the getter already works
  2. Or at least the error message should be changed as it’s misleading, indexing itself has no problem.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:9
  • Comments:20 (8 by maintainers)

github_iconTop GitHub Comments

3reactions
MartinJohnscommented, Jan 9, 2022

The type of the property a is "hello", not the value (well, the value is too). It’s a property that can only accept the string literal "hello", but it can not accept the string "". It’s more common used with union types, e.g. "a" | "b". Meaning it can only be the string "a", or the string "b", but not any other string.

type Test = { val: "a" | "b" }
const t: Test = { val: "a" }
t.val = "b" // is okay
t.val = "" // is not okay
2reactions
fatcerberuscommented, Apr 7, 2022

@Tinadim T is a type parameter, which means that it can be anything that’s assignable to its constraint (i.e. extends is not necessarily a subtyping relationship). This is maybe a bit counterintuitive, but being constrained by a type with an index signature doesn’t guarantee that T also has one:

interface Foo {
    [key: string]: number;
}

function test<T extends Foo>(a: T) {
    a['test'] = 1234;  // error
}

const x = { foo: 1, bar: 2 };
test(x);  // no error, valid call

test(x) is legal, but x['test'] = 1234; is not. Therefore, the assignment inside test is also invalid. When you write a generic function, it’s not just the value that varies, but the type as well, so the compiler wants to ensure that what you write inside the function is valid for all possible types T can be.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Type '"test"' cannot be used to index type 'T' - Stack Overflow
Note that for type inference to work, you'll need to pass a parameter to the function that uses one or more of the...
Read more >
Type 'String' cannot be used as an index type in TypeScript
The "Type 'String' cannot be used as an index type" TypeScript error occurs when we use the String type instead of string (lowercase...
Read more >
Type 'string' cannot be used to index type 'T' while T extends ...
I wrote the following rename function: const rename = <T extends Record<string, any>>(object: T, namesMap: Record<string, string>) ...
Read more >
How To Let a TypeScript Function Accept an Index Type as ...
You will get an error like “Element implicitly has an 'any' type because expression of type 'string' can't be used to index type...
Read more >
element implicitly has an 'any' type because ... - You.com
'...expression of type string cannot be used to index...' ... You need to further constrain your generic type parameter: function ReturnFirst<Type extends ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found