You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
error TS2677: Type 'keyof E' is not assignable to type 'string' #23724
//Just a minimal example, not what I am actually doingfunctionisKey<E>(str : string) : str is keyofE{returntrue;}
Expected behavior:
Should compile fine. The body of the type guard may actually correctly assert that str is, indeed, keyof E
Works fine on TypeScript 2.8.3
Actual behavior:
error TS2677: A type predicate's type must be assignable to its parameter's type.
Type 'keyof E' is not assignable to type 'string'.
Type 'string | number | symbol' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'
This is a breaking change in TS 2.9 (documentation should come soon) introduced by #23592. With #23592keyof now returns all known keys of a types including string, number and symbol keys. and as such, the constraint on keyof E is now string | number | symbol.
If you are interested in getting only the string portions of the keys, use Extract:
functionisKey<E>(str: string): str is Extract<keyofE,string>{returntrue;}
if your function is meant to handle all property names, including symbols, then consider widening the declaration of str:
functionisKey<E>(str : string|number|symbol) : str is keyofE{returntrue;}
Reacted by AnyhowStep, Kagami Sascha Rosylight, Cristiano Santos, Arman Dezfuli-Arjomandi, Artem Malko, Dmitry, Christoph Lütjen, Viktor, Lihao Lin, Melchor Garau Madrigal and 50 more
Reacted by netnichaa, Charlie Walter, Jonathan Tuzman, Renato Araujo Carneiro, Cethy and Jacob Coughenour
Reacted by Musa, Dan Minshew, Abhishek Datta, Yann RENAUDIN, Jorge Martins, netnichaa, Scott Bedard, Tate Thurston, Christian, banana and 5 more
Reacted by netnichaa, Donghyun Lee, Tate Thurston, Charlie Walter, Renato Araujo Carneiro and Rémi Becheras
However, if I specifically mention that my type has only string keys like this:
interfaceA{[k: string]: any;}typeb=keyofA;
still, I get the type of b as string | number as seen in the IntelliSense on vs code:
Why is that so? Why is it not string only?
Typescript used: 3.9.3
Reacted by Gustavo, Axel Bocciarelli, Richard Kemp, Avétis KAZARIAN, Stanley Stuart, S. Tarık Çetin, Shane Gardner, silentvow, Aria, AdrianDiazG and 8 more
Activity
mhegazy commentedon Apr 26, 2018
This is a breaking change in TS 2.9 (documentation should come soon) introduced by #23592. With #23592
keyofnow returns all known keys of a types includingstring,numberandsymbolkeys. and as such, the constraint onkeyof Eis nowstring | number | symbol.If you are interested in getting only the string portions of the keys, use
Extract:if your function is meant to handle all property names, including symbols, then consider widening the declaration of
str:ahejlsberg commentedon Apr 26, 2018
Also, as a temporary measure you can use the new
--keyofStringsOnlycompiler option to revert to the old behavior.AnyhowStep commentedon Apr 27, 2018
Thanks for the swift response!
Fix TypeScript 2.9 build
Change tsconfig.json to be able to execute tsc in watch mode
abdatta commentedon Jun 4, 2020
However, if I specifically mention that my type has only string keys like this:
still, I get the type of b as

string | numberas seen in the IntelliSense on vs code:Why is that so? Why is it not string only?
Typescript used: 3.9.3
SLGShark6 commentedon Jan 30, 2021
For typescript 4, I use this in place of keyof as a current workaround to get accurate key types