Refine property skipping logic and update identity properties by excluding 'kind'

This commit is contained in:
2026-04-27 15:53:15 +02:00
parent c3dd68e682
commit 2870ac93f9

View File

@@ -121,7 +121,7 @@ const ROOTS: readonly AuthorableRoot[] = [
} }
]; ];
const IDENTITY_PROPERTIES = new Set(["id", "version", "kind"]); const IDENTITY_PROPERTIES = new Set(["id", "version"]);
const DISCRIMINATOR_CANDIDATES = [ const DISCRIMINATOR_CANDIDATES = [
"mode", "mode",
"type", "type",
@@ -276,6 +276,29 @@ function literalUnionLabels(type: ts.Type): string[] {
return labels.length === parts.length ? labels : []; return labels.length === parts.length ? labels : [];
} }
function shouldSkipProperty(
propertyName: string,
propertyType: ts.Type | null,
options: {
skipProperties: ReadonlySet<string>;
skipPropertiesForThisObject?: ReadonlySet<string>;
}
): boolean {
if (
IDENTITY_PROPERTIES.has(propertyName) ||
options.skipProperties.has(propertyName) ||
options.skipPropertiesForThisObject?.has(propertyName)
) {
return true;
}
if (propertyName !== "kind" || propertyType === null) {
return false;
}
return literalUnionLabels(propertyType).length === 1;
}
function chooseDiscriminator(types: readonly ts.Type[]): string | null { function chooseDiscriminator(types: readonly ts.Type[]): string | null {
for (const candidate of DISCRIMINATOR_CANDIDATES) { for (const candidate of DISCRIMINATOR_CANDIDATES) {
const labels = types const labels = types
@@ -392,6 +415,7 @@ function collectUnionFields(
if ( if (
discriminator !== null && discriminator !== null &&
discriminator !== "kind" &&
!IDENTITY_PROPERTIES.has(discriminator) && !IDENTITY_PROPERTIES.has(discriminator) &&
!options.skipProperties.has(discriminator) !options.skipProperties.has(discriminator)
) { ) {
@@ -411,8 +435,7 @@ function collectUnionFields(
commonPropertyNames.filter((name) => { commonPropertyNames.filter((name) => {
if ( if (
name === discriminator || name === discriminator ||
IDENTITY_PROPERTIES.has(name) || shouldSkipProperty(name, getPropertyType(objectTypes[0]!, name), options)
options.skipProperties.has(name)
) { ) {
return false; return false;
} }
@@ -490,20 +513,16 @@ function collectObjectFields(
for (const property of type.getProperties()) { for (const property of type.getProperties()) {
const propertyName = property.name; const propertyName = property.name;
if (
IDENTITY_PROPERTIES.has(propertyName) ||
options.skipProperties.has(propertyName) ||
options.skipPropertiesForThisObject?.has(propertyName)
) {
continue;
}
const declaration = property.valueDeclaration ?? property.declarations?.[0]; const declaration = property.valueDeclaration ?? property.declarations?.[0];
const propertyType = checker.getTypeOfSymbolAtLocation( const propertyType = checker.getTypeOfSymbolAtLocation(
property, property,
declaration ?? propertyDeclarationsFallback() declaration ?? propertyDeclarationsFallback()
); );
if (shouldSkipProperty(propertyName, propertyType, options)) {
continue;
}
collectFields(propertyType, `${currentPath}.${propertyName}`, entries, { collectFields(propertyType, `${currentPath}.${propertyName}`, entries, {
condition: options.condition, condition: options.condition,
skipProperties: options.skipProperties skipProperties: options.skipProperties