Skip to content

Instantly share code, notes, and snippets.

@hilleer
Last active March 12, 2024 15:08
Show Gist options
  • Save hilleer/521b4cbcebbf487f5023cd81e936f4d6 to your computer and use it in GitHub Desktop.
Save hilleer/521b4cbcebbf487f5023cd81e936f4d6 to your computer and use it in GitHub Desktop.
Typescript dynamic typeof object key with type definitions for key values example
const GAMES = Object.freeze({
CSGO: {
skillLevel: 'good'
},
WOW: {
skillLevel: 'average'
}
});
type GameKey = keyof typeof GAMES;
function getGameInfo(key: GameKey) {
return GAMES[key];
}
getGameInfo('CSGO');
getGameInfo('WOW');
getGameInfo('unknown') // COMPILE ERROR HERE
// ------------------------
// Same scenario, working with helper function to actually force types of the values
type GameInfo = { [key: string]: { skillLevel: 'good' | 'average' | 'bad' }}
function enforceObjectType<T extends GameInfo>(o: T) {
return Object.freeze(o);
}
const GAMES2 = enforceObjectType({
CSGO: {
skillLevel: 'good',
},
WOW: {
skillLevel: 'average'
},
DOTA: {
// Compile error - missing property skillLevel
}
});
type GameKey2 = keyof typeof GAMES2;
function getGameInfo2(key: GameKey2) {
return GAMES[key];
}
getGameInfo2('WOW');
getGameInfo2('CSGO');
getGameInfo2('unknown') // COMPILE ERROR HERE
@hilleer
Copy link
Author

hilleer commented Apr 4, 2020

I found this solution to be solving the needs, although not entirely free of using JS to define the types:

type GameInfo = { [key: string]: { skillLevel: 'good' | 'average' | 'bad' }}

type EnforceObjectType<T> = <V extends T>(v: V) => V;
const enforceObjectType: EnforceObjectType<GameInfo> = v => v;

const GAMES2 = enforceObjectType({
  CSGO: {
    skillLevel: 'good',
  },
  WOW: {
    skillLevel: 'average'
  },
  DOTA: {
    // Compile error - missing property skillLevel
  }
});

type GameKey2 = keyof typeof GAMES2;

function getGameInfo2(key: GameKey2) {
  return GAMES2[key];
}

getGameInfo2('WOW');
getGameInfo2('CSGO');
getGameInfo2('unknown') // COMPILE ERROR HERE

typescript playground

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment