Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent type inference for additionalProperties when properties is also defined #199

Open
alvis opened this issue May 13, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@alvis
Copy link

alvis commented May 13, 2024

Encountering a bug in json-schema-to-ts version 3.1.0 where the handling of additionalProperties does not work as expected when properties is also provided. Instead of assigning the designated type to additional properties, they are treated as unknown.

Example to reproduce:

import type { FromSchema } from 'json-schema-to-ts';

type Output = FromSchema<{
  type: 'object';
  additionalProperties: { type: 'string' };
  properties: {
    something: { type: 'string' };
  };
}>;

Expected behavior:

type Output = {
    [x: string]: string | undefined;
    something?: string | undefined;
}

Actual behavior:

type Output = {
    [x: string]: unknown;
    something?: string | undefined;
}

The expected behavior would be to treat all additional properties as string or string | undefined (which makes more sense when it comes to dealing with the unknown and type compliant to the non required additional properties), aligning with the specified additionalProperties type.

@ThomasAribart
Copy link
Owner

ThomasAribart commented May 13, 2024

Hi @alvis ! This was already an issue before v3.1, so I would consider this an improvement rather than a bug.

As specified in the documentation, what is tricky is that additionalProperties and properties could be in conflict once transformed into types:

const validSchema = {
  type: "object",
  additionalProperties: { enum: ["foo", "bar"] },
  properties: {
    something: { type: "string" },
  },
} as const;

// { [x: string]: "foo" | "bar"; something: string; }
type InvalidType = FromSchema<typeof validSchema>;

// 'something' is an example of string so TS expects 'foo' or 'bar'
const conflict: InvalidType = { something: "baz" };

There is a case however for keeping the type of additionalProperties if it extends the union of all the properties. This is a bit tricky to do but can probably be done in https://github.com/ThomasAribart/ts-algebra. I'll have a look.

@ThomasAribart ThomasAribart added the enhancement New feature or request label May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants