json-schema-to-typescript
json-schema-to-typescript copied to clipboard
Feature request: Support OpenAPI's "discriminator" directive
In AOS 3 there's provision for oneOf being used along with a discriminator, which allows specifying an array where the types are discriminated based on a property. https://swagger.io/docs/specification/data-models/oneof-anyof-allof-not/
{
"definitions": {
"Ledger": {
"required": [
"transactions"
],
"type": "object",
"properties": {
"transactions": {
"uniqueItems": false,
"type": "array",
"items": {
"oneOf": [
{
"$ref": "#/definitions/JournalingTransaction"
},
{
"$ref": "#/definitions/SalesReturnTransaction"
}
],
"discriminator": "transactionType"
}
}
}
},
"TransactionType": {
"enum": [
"JournalingTransaction",
"SalesReturnTransaction"
],
"type": "string",
"tsEnumNames": [
"JournalingTransaction",
"SalesReturnTransaction"
]
},
"AccountEntry": {
"amount": {
"format": "double",
"type": "number"
}
},
"Transaction": {
"required": [
"transactionType",
"accountEntries"
],
"type": "object",
"properties": {
"transactionType": {
"$ref": "#/definitions/TransactionType"
},
"accountEntries": {
"uniqueItems": false,
"type": "array",
"items": {
"$ref": "#/definitions/AccountEntry"
}
}
}
},
"JournalingTransaction": {
"allOf": [
{
"$ref": "#/definitions/Transaction"
},
{
"required": [
"reason"
],
"type": "object",
"properties": {
"reason": {
"type": "string"
}
}
}
]
},
"SalesReturnTransaction": {
"allOf": [
{
"$ref": "#/definitions/Transaction"
},
{
"required": [
"returnItemId"
],
"type": "object",
"properties": {
"returnItemId": {
"type": "string"
}
}
}
]
}
}
}
Expected TypeScript:
export interface Ledger {
transactions: (
| JournalingTransaction
| SalesReturnTransaction)[];
}
export const enum TransactionType {
JournalingTransaction = 'JournalingTransaction',
SalesReturnTransaction = 'SalesReturnTransaction'
}
export interface AccountEntry {
amount: number;
}
export interface Transaction {
accountEntries: AccountEntry[];
}
export type JournalingTransaction = Transaction & {
transactionType: TransactionType.JournalingTransaction;
reason: string;
};
export type SalesReturnTransaction = Transaction & {
transactionType: TransactionType.SalesReturnTransaction;
returnItemId: string;
};
Will leave this open for now, in case there's interest from others in this feature.
Is that a valid schema for the discriminator? I don't see any way of linking SalesReturnTransaction to TransactionType.SalesReturnTransaction other than them having the same name which seems flaky.