Typescript: Type 'keyof T' does not satisfy the constraint 'string'.

Created on 27 Jun 2018  路  9Comments  路  Source: microsoft/TypeScript


TypeScript Version: 3.0.0-dev.201xxxxx
Issue still happens on dev version.


Search Terms: keyof T

Code

I am getting this error in Typescript 2.9.
```/node_modules/@types/react-router/index.d.ts
(106,55): Type 'keyof T' does not satisfy the constraint 'string'.
Type 'string | number | symbol' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.


This is the line that deals with keyof T in the react router types index.d.ts

type Omit = Pick ```

Expected behavior:
When I used Typescript 2.8 this error did not show up. However, when I updated Typescript the error showed up. The react router types should work properly like in 2.8.

Actual behavior:
I am getting the error above.

Playground Link:
No link but I am using react router with Typescript.

Related Issues:
No related issues.

Question

Most helpful comment

The only solution as of now is to use a flag and disable this new behaviour. Fixing the packages by hand is senseless.

_tsconfig.json_

"keyofStringsOnly": true

All 9 comments

Breaking change since 2.9: https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#keyof-now-includes-string-number-and-symbol-keys

The only solution as of now is to use a flag and disable this new behaviour. Fixing the packages by hand is senseless.

_tsconfig.json_

"keyofStringsOnly": true

I'm having this issue too, and I don't understand what's going on well enough to resolve it.

Most packages seem to have updated their typings to avoid this, including react-router. However, some dependencies seem to come with their own @types dependencies, as shown in my error case:

Failed to compile.

[at-loader] ./node_modules/@types/react-router-redux/node_modules/@types/react-router/index.d.ts:106:55 
    TS2344: Type 'keyof T' does not satisfy the constraint 'string'.
  Type 'string | number | symbol' is not assignable to type 'string'.
    Type 'number' is not assignable to type 'string'.

As you can see, the error is coming from react-router-redux's own @types dependency, which I was surprised existed in my project hierarchy to begin with...

react-router has updated their types for TS 2.9, however the typing file for react-router that is _within_ react-router-redux in this error message (./node_modules/@types/react-router-redux/node_modules/@types/react-router/index.d.ts) does not have this update. I don't see a place in the react-router-redux package.json where I could try and fix this, so I'm not sure where this older version of the @types file is coming from. Does anyone know?

My project does not even directly depend on the @types/react-router it turns out, though I tried adding the updated version as a direct dependency to resolve this by adding "@types/react-router": "^4.0.27", to my "dependencies" list. That didn't work; I ended up with two entries in my yarn.lock:


"@types/react-router-dom@^4.0.8":
  version "4.2.6"
  resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-4.2.6.tgz#9f7eb3c0e6661a9607d878ff8675cc4ea95cd276"
  dependencies:
    "@types/history" "*"
    "@types/react" "*"
    "@types/react-router" "*"

"@types/react-router-redux@^5.0.15":
  version "5.0.15"
  resolved "https://registry.yarnpkg.com/@types/react-router-redux/-/react-router-redux-5.0.15.tgz#aebc593bd3426adb6ae2eba6ac8c919ee232ce7b"
  dependencies:
    "@types/history" "*"
    "@types/react" "*"
    "@types/react-router" "*"
    redux ">= 3.7.2"

"@types/react-router@*":
  version "4.0.23"
  resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-4.0.23.tgz#d0509dcbdb1c686aed8f3d5cb186f42e5fbe7c2a"
  dependencies:
    "@types/history" "*"
    "@types/react" "*"

"@types/react-router@^4.0.27":
  version "4.0.27"
  resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-4.0.27.tgz#553f54df7c4b09d6046b0201ce9b91c46b2940e3"
  dependencies:
    "@types/history" "*"
    "@types/react" "*"

Why would the "@types/react-router@*": dependency resolve to this older 4.0.23 when 4.0.27 exists (and I've added it manually?)

possibly related to https://github.com/Microsoft/TypeScript/issues/11917 but I don't really understand completely, so I could be wrong.

by way of https://stackoverflow.com/a/49126573/2544629 I figured I'd give this a shot:

rm yarn.lock
yarn

which completely wipes out your yarn.lock and regenerates it. Maybe I could have done this another way, like removing and then re-adding all packages that required "@types/react-router@*" so that package was removed, but this worked out for me.

@jjwatt99 , since it wasn't clear from your OP, you should try updating your types file for react-router by running yarn add @types/react-router . They've fixed the bug you're referring to there (https://github.com/DefinitelyTyped/DefinitelyTyped/commit/5c516d012a9d094df062f804ab4b61034282af5c#diff-bc5f906a3af0cde1a95a8a23cb993e96).

Typescript is also complaining about indexed type:

type A={[key:string]:any}
function(a:keyof A)
{
    return a.substr(1);
}

In that case, should not it be enforced to be string only ?

@npenin a string index signature also implies the type can be indexed with a number given how JS coerces property names under the hood.

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

Extract did the trick for me.
I found this in @j-oliveras 's post. Thx man!

I tried adding Extract but it did nothing, any ideas what I'm doing wrong?

function groupBy<T extends Record<K, PropertyKey>, K extends Extract<keyof T, string>>(
  items: readonly T[],
  key: K
) {
  return items.reduce((acc, item) => {
    (acc[item[key]] = acc[item[key]] || []).push(item);
    return acc;
  }, {} as Record<T[K], T[]>); // Still has an error at T[K]
}
Type 'T[K]' does not satisfy the constraint 'string'.ts(2344)
Type 'T[K]' does not satisfy the constraint 'string'.
  Type 'T[Extract<keyof T, string>]' is not assignable to type 'string'. // Huh?
    Type 'T[keyof T]' is not assignable to type 'string'.
      Type 'T[string]' is not assignable to type 'string'.
        Type 'string | number | symbol' is not assignable to type 'string'.
          Type 'number' is not assignable to type 'string'.ts(2344)

And if I do this:

function groupBy<T extends Record<K, PropertyKey>, K extends Extract<keyof T, string>>(
  items: readonly T[],
  key: K
) {
  return items.reduce((acc, item) => {
    (acc[item[key]] = acc[item[key]] || []).push(item);
    return acc;
  }, {} as Record<Extract<T[K], string>, T[]>);
}

The error goes away but I get new errors on the acc[item[key]] line: Type 'T[K]' cannot be used to index type 'Record<Extract<T[K], string>, T[]>'.ts(2536)

Edit The original code worked fine when I changed compileOptions.module from "ESNext" to "UMD" or "ES6" huh?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bgrieder picture bgrieder  路  3Comments

wmaurer picture wmaurer  路  3Comments

uber5001 picture uber5001  路  3Comments

jbondc picture jbondc  路  3Comments

kyasbal-1994 picture kyasbal-1994  路  3Comments