#Building declarations with values of object literal instead of just the type

28 messages · Page 1 of 1 (latest)

ember dagger
#

I'm trying to expose an object literal from a package such that all of the defined properties of the object will be preserved, and viewable when the package is imported and used in some file. For this, I need the shape of the object in the resulting declarations file to not just be the type it is defined as, but the specific properties also.
For example, foo.ts without any typing applied (it is basically it's own type).

const foo = {
  bar: 123,
  baz: "abc",
};

export default foo;

which compiles to foo.d.ts

declare const foo: {
    bar: number;
    baz: string;
};
export default foo;

and bar and baz show up as properties of foo when imported and used. All is well.

But now I want to enforce a type on foos properties, to prevent them from being anything.
For example, now I want them all to be numbers (or some other custom type).
So I restrict all of the properties to be only of number type like so in foo.ts.

const foo: { [key: string]: number } = {
  bar: 123,
  baz: 456,
};

export default foo;

foo.d.ts

declare const foo: {
    [key: string]: number;
};
export default foo;

which removes all knowledge of the actual properties of foo, in favour of just showing the type of all properties it may have.

How to achieve the property names being included in the declaration, without leaving the original object untyped?

solar bluff
#

have you tried with as const?

#
const foo = {
  bar: 123,
  baz: "abc",
} as const;

export default foo;
#

@ember dagger

ember dagger
#

foo is still basically untyped

solar bluff
#
const foo = {
  bar: 123,
  baz: "abc",
};
#

!ts foo

eternal plankBOT
#
const foo: {
    bar: number;
    baz: string;
} /* 1:7 */```
solar bluff
#
const foo = {
  bar: 123,
  baz: "abc",
} as const;
#

!ts foo

eternal plankBOT
#
const foo: {
    readonly bar: 123;
    readonly baz: "abc";
} /* 1:7 */```
ember dagger
#

bar and baz (and any propery defined on foo) should only be numbers

#

hence the { [key: string]: number }

#

idk if you understood my question right

solar bluff
#

arrow but there is a problem in what you're doing

#

by giving a type explicitly, you're removing those litteral values

#

so don't do { [key: string]: number }

#

is ou still want to make sure the object respects a certain shape, use the satisfies operator

#
const foo = {
    bar: 123,
    baz: 456,
} as const satisfies Record<string, number>;
#

!ts foo

eternal plankBOT
#
const foo: {
    readonly bar: 123;
    readonly baz: 456;
} /* 1:7 */```
ember dagger
#

huh, cool

#

never seen satisfies before

#

I should probably look at new features once in a while haha

solar bluff
#

!resolved