#Object with key as one type and all other types as object

18 messages · Page 1 of 1 (latest)

simple shard
#

I want to type an object like so;

const obj = { hello: true, somethingElse: {} };

Currently this does not work as a type:

type Obj = { hello: boolean, [key: string]: object };

I’ve tried work arounds using omit etc but not sure what the correct way of doing this would be.

warm phoenix
#

!:known*

timid portalBOT
#
retsam19#0
`!retsam19:known-and-unknown-keys`:

TS doesn't work well with objects that mix "known keys" of one type onto an object with unknown keys (i.e. an index signature) for a different type.

type DoesNotCompile = {
    [key: string]: number; // all unknown keys are numbers
    specificKey: string; // but this key is a string
}

You can 'fake' it with intersections:

type Compiles = { [key: string]: number;}
  & { specificKey: string };

but this type is essentially read-only. You can read from it as you'd expect, but you can't assign anything to this type (without an assertion).

If your API isn't set in stone, it's recommended to put the unknown keys in their own object:

type Idiomatic ={
   specificKey: string;
   unknownKeys: Record<string, number>;
}
simple shard
#

Hmm that response isn’t very good

fleet yoke
#

i mean, it's how ts works, what other response do you want

warm phoenix
#

"Isn't very good" as in "you misunderstood my question, I'm not asking about mixing known and unknown keys" or something else?

simple shard
#

The Compiles type doesn’t work though, you can’t do an intersection.

#

The unknown objects isn’t ideal.

#

The intersection would only work if key: string is type string | number so that type is already wrong in the answer, but ideally I would want with just string but it just doesn’t work that way.

#

Can you show me an assertion example?

warm phoenix
#

The compile type does work though?

timid portalBOT
#
// No compile error
type Compiles = { [key: string]: number;}
  & { specificKey: string };
simple shard
#

I want to use it as type, if I assign it to my obj then it’ll complain

warm phoenix
#

Yes, that's what's said in the snippet.

#

but this type is essentially read-only. You can read from it as you'd expect, but you can't assign anything to this type (without an assertion).

#

Which leads up to the conclusion that if you can change your API, change it so you are not mixing known and unknown keys.

fleet yoke
simple shard
#

Thank you! I will resolve this issue 🙂