in packages/typespec-powershell/src/utils/modelUtils.ts [588:662]
function validateDiscriminator(
program: Program,
discriminator: Discriminator,
derivedModels: readonly Model[]
): boolean {
const { propertyName } = discriminator;
const retVals = derivedModels.map((t) => {
const prop = getProperty(t, propertyName);
if (!prop) {
reportDiagnostic(program, {
code: "discriminator",
messageId: "missing",
target: t
});
return false;
}
let retval = true;
if (
!isOasString(prop.type) &&
prop.type.kind !== "EnumMember" &&
prop.type.kind !== "Enum"
) {
reportDiagnostic(program, {
code: "discriminator",
messageId: "type",
target: prop
});
retval = false;
}
if (prop.optional) {
reportDiagnostic(program, {
code: "discriminator",
messageId: "required",
target: prop
});
retval = false;
}
return retval;
});
// Map of discriminator value to the model in which it is declared
const discriminatorValues = new Map<string, string>();
for (const t of derivedModels) {
// Get the discriminator property directly in the child model
const prop = t.properties?.get(propertyName);
// Issue warning diagnostic if discriminator property missing or is not a string literal
if (!prop || !isStringLiteral(prop.type)) {
reportDiagnostic(program, {
code: "discriminator-value",
messageId: "literal",
target: prop || t
});
}
if (prop) {
const vals = getStringValues(prop.type);
vals.forEach((val) => {
if (discriminatorValues.has(val)) {
reportDiagnostic(program, {
code: "discriminator",
messageId: "duplicate",
format: {
val: val,
model1: discriminatorValues.get(val)!,
model2: t.name
},
target: prop
});
retVals.push(false);
} else {
discriminatorValues.set(val, t.name);
}
});
}
}
return retVals.every((v) => v);
}