Zork look-a-like written in TypeScript
From my experiences in MUDs and text games, I think you would do well to create a class/module that handles each command then inject them into your processor (even manually). It will help a lot with the maintainability but also isolating commands.

import {registerLook} from "./commands/look";
import {registerGo} from "./commands/go";

// Build up a hash of commands. With a MUD style, you would register the shorten
// versions also (so look registers as "l", "lo", "loo", and "look") but removes
// entries that would have a conflict (so "left" would remove the "l" for look but
// register "le", "lef", and "left".
let commands = {};

registerLook(commands);
registerGo(commands);

// Then when you are running the command.
if (command.action in commands
{
  commands[command.action].run(command, receiver);
}
else
{
  // Show error of missing command
}


You could go further with the SOLID implementation by having the commands injected from the top-level, but the main reason for doing this is to let you have the complex logic for the commands moved into a separate file that does one thing only (Single Responsibility Principle) while treating the switch of the commands against an interface (functions inserted into the hash by a register).

Ideally, having a DI figure out the commands would be nice, but I haven't found a good DI system for Typescript I like. (You could also scan the commands directory and inject the commands that way.)

It also lets you nest the commands if you need to. So if you have look at and look into, you could have commands/look.ts break apart the first word and then pass it into look commands (commands/look/at.ts) to further isolate it. Or whatever makes sense.