1

I have the following issue, where the typescript compiler allows additional properties, that should not be allowed... I marked the line below. Basically the compiler allows additional properties of Command, while I thought they should not be allowed.

EDIT: Refactored self-contained example

type CommandData = { [key: string]: unknown }
type BaseState = { id: string; }

export type Command<
  Type extends string = string,
  Data extends CommandData = CommandData,
> = {
  id: string;
  payload: Data;
  type: Type;
};

export type PreHook<StateModel extends BaseState = BaseState, Commands extends Command = Command> = ({
  command,
  state,
}: {
  command: Commands;
  state: StateModel;
}) => Promise<{ command: Commands; state: StateModel }>;

const preHook: PreHook = async ({ command, state }) => ({
  command: { ...command, metadata: { foo: "bar" }, foo: "bar" }, // <-- METADATA AND FOO SHOULD NOT BE ALLOWED, BUT COMPILER DOES NOT ERROR
  state: { ...state },
});

florian norbert bepunkt
  • 2,099
  • 1
  • 21
  • 32
  • `CommandData`, `CommandContext`, `BaseState`, `Model`, `Commands`. What are they? Could you provide a [mre] where you either define these or, even better, remove them? – jcalz Apr 01 '23 at 17:01
  • jcalz is the resident expert here, but to me this just looks like duck typing in action. I also think that [this post](https://stackoverflow.com/questions/49580725/is-it-possible-to-restrict-typescript-object-to-contain-only-properties-defined) is very related to your question, although it is a couple years old so it's always possible there is some new TS magic that I don't know about... – Jake Apr 01 '23 at 17:33
  • Yes, excess properties are generally allowed and only warned about in particular situations. Maybe spread should be one of them but it's not. Without a [mre] I'm not particularly inclined to do much here, though. – jcalz Apr 01 '23 at 22:42
  • 1
    @jcalz I refactored the example. Btw: I profited a lot from your answers to a variety of TS problems. Thank you for your efforts here on SO. – florian norbert bepunkt Apr 02 '23 at 20:25
  • What is the purpose of the generic type parameters here if you're not using them? Can you reduce the example to [this version](https://tsplay.dev/NB8ypW) without affecting the question? A [mre] should be minimal as well as reproducible. Indeed it can probably be reduced to [this version](https://tsplay.dev/mbvB4m), maybe even further, unless there's something you're trying to convey with the more complex version. How should we proceed? – jcalz Apr 02 '23 at 22:19
  • Actually before you consider [edit]ing anything, would you say this is the same issue as [this question](https://stackoverflow.com/questions/59318739/is-there-an-option-to-make-spreading-an-object-strict)? If so we can just mark it as a duplicate. If not, what am I missing about it? – jcalz Apr 02 '23 at 22:21
  • 1
    Thank you for the reference to the other question. Yes, in the end it's the same issue. – florian norbert bepunkt Apr 03 '23 at 13:52

0 Answers0