Repository: vega/ts-json-schema-generator (ts)

Issue:
Incorrect `additionalProperties` schema generated for `Pick<T, AliasLiteralUnion>`
When using `Pick<T, AliasLiteralUnion>` - where the union is composed of type aliases to literal strings - the generator incorrectly emits an `additionalProperties` sub-schema (e.g., `{ "type": ... }`) instead of respecting the `--additional-properties` setting.

## Reproduction:

```ts
interface SomeInterface {
  foo: string;
  bar: number;
}

type AliasFoo = "foo";
type AliasBar = "bar";

export type PickUnionOfLiteralsAliases = Pick<SomeInterface, AliasFoo | AliasBar>;
```

## Expected Output ✅
```json
"PickUnionOfLiteralsAliases": {
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "number" }
  },
  "required": ["foo", "bar"],
  "additionalProperties": false
}
```
This is the correct output, and it's exactly what the generator produces when the union is written inline:
```ts
export type PickWithLiteralUnion = Pick<SomeInterface, "foo" | "bar">;
```

## Current Output ❌
However, when using aliases, we get:
```json
"PickUnionOfLiteralsAliases": {
  "type": "object",
  "properties": {
    "foo": { "type": "string" },
    "bar": { "type": "number" }
  },
  "required": ["foo", "bar"],
  "additionalProperties": { "type": "string" }  // ← unexpected
}
```

## Root cause
In `MappedTypeNodeParser.getAdditionalProperties()`, the logic to detect non-literal keys does not unwrap aliases:

```ts
const key = keyListType.getTypes().filter((type) => !(type instanceof LiteralType))[0];
```

As a result, keys like:
```ts
type AliasFoo = "foo";
```
…are not recognized as literals, and the generator assumes an open-ended keyset.

## Proposed fix 
Update the filtering logic to unwrap aliases using `derefType()`:

```ts
const key = keyListType.getTypes().filter((type) => !(derefType(type) instanceof LiteralType))[0];
```


Pull request:
fix: avoid incorrect additionalProperties for Pick<..., AliasLiteralUnion>
Closes #2229 

Patch:
diff --git a/src/NodeParser/MappedTypeNodeParser.ts b/src/NodeParser/MappedTypeNodeParser.ts
index 4a597d0..9fe6e21 100644
--- a/src/NodeParser/MappedTypeNodeParser.ts
+++ b/src/NodeParser/MappedTypeNodeParser.ts
@@ -158,7 +158,7 @@ export class MappedTypeNodeParser implements SubNodeParser {
         keyListType: UnionType,
         context: Context,
     ): BaseType | boolean {
-        const key = keyListType.getTypes().filter((type) => !(type instanceof LiteralType))[0];
+        const key = keyListType.getTypes().filter((type) => !(derefType(type) instanceof LiteralType))[0];
 
         if (key) {
             return (


Test patch:
diff --git a/test/valid-data-type.test.ts b/test/valid-data-type.test.ts
index 8e06518..0687838 100644
--- a/test/valid-data-type.test.ts
+++ b/test/valid-data-type.test.ts
@@ -88,6 +88,7 @@ describe("valid-data-type", () => {
     it("type-keyof-tuple", assertValidSchema("type-keyof-tuple", "MyType"));
     it("type-keyof-object", assertValidSchema("type-keyof-object", "MyType"));
     it("type-keyof-object-function", assertValidSchema("type-keyof-object-function", "MyType"));
+    it("type-mapped-pick-union-alias", assertValidSchema("type-mapped-pick-union-alias", "PickAliasedLiteralUnion"));
     it("type-mapped-simple", assertValidSchema("type-mapped-simple", "MyObject"));
     it("type-mapped-index", assertValidSchema("type-mapped-index", "MyObject"));
     it("type-mapped-index-as", assertValidSchema("type-mapped-index-as", "MyObject"));
diff --git a/test/valid-data/type-mapped-pick-union-alias/main.ts b/test/valid-data/type-mapped-pick-union-alias/main.ts
new file mode 100644
index 0000000..eae7783
--- /dev/null
+++ b/test/valid-data/type-mapped-pick-union-alias/main.ts
@@ -0,0 +1,9 @@
+interface SomeInterface {
+    foo: string;
+    bar: number;
+}
+
+type KeyFoo = "foo";
+type KeyBar = "bar";
+
+export type PickAliasedLiteralUnion = Pick<SomeInterface, KeyFoo | KeyBar>;
diff --git a/test/valid-data/type-mapped-pick-union-alias/schema.json b/test/valid-data/type-mapped-pick-union-alias/schema.json
new file mode 100644
index 0000000..e04bcad
--- /dev/null
+++ b/test/valid-data/type-mapped-pick-union-alias/schema.json
@@ -0,0 +1,22 @@
+{
+  "$ref": "#/definitions/PickAliasedLiteralUnion",
+  "$schema": "http://json-schema.org/draft-07/schema#",
+  "definitions": {
+    "PickAliasedLiteralUnion": {
+      "additionalProperties": false,
+      "properties": {
+        "bar": {
+          "type": "number"
+        },
+        "foo": {
+          "type": "string"
+        }
+      },
+      "required": [
+        "foo",
+        "bar"
+      ],
+      "type": "object"
+    }
+  }
+}