From bf599fa8d13f01b3db4e6e1b4b4af63d8ea2df4c Mon Sep 17 00:00:00 2001 From: Mary Gao Date: Tue, 5 Mar 2024 16:02:46 +0800 Subject: [PATCH 1/6] Update the changes --- packages/typespec-ts/src/utils/modelUtils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/typespec-ts/src/utils/modelUtils.ts b/packages/typespec-ts/src/utils/modelUtils.ts index 48200666c2..dd0af7ebb0 100644 --- a/packages/typespec-ts/src/utils/modelUtils.ts +++ b/packages/typespec-ts/src/utils/modelUtils.ts @@ -229,7 +229,8 @@ export function getSchemaForType( return undefined; } export function getEffectiveModelFromType(program: Program, type: Type): Type { - if (type.kind === "Model") { + // Only adopt the logic from getEffectiveModelType when it is anonymous model + if (type.kind === "Model" && type.name === "") { const effective = getEffectiveModelType(program, type, isSchemaProperty); if (effective.name) { return effective; From 7da5598661c18ce621b86b61e77aa4b0e598f7b3 Mon Sep 17 00:00:00 2001 From: Mary Gao Date: Tue, 5 Mar 2024 19:06:10 +0800 Subject: [PATCH 2/6] Only adopt the getEffectiveModelType for anonymous model --- .../typespec-ts/src/modular/buildCodeModel.ts | 13 ++++++--- packages/typespec-ts/src/utils/modelUtils.ts | 5 +++- .../typespec-ts/test/modularUnit/type.spec.ts | 27 +++++++++++++++++- .../test/unit/modelsGenerator.spec.ts | 28 +++++++++++++++++++ 4 files changed, 67 insertions(+), 6 deletions(-) diff --git a/packages/typespec-ts/src/modular/buildCodeModel.ts b/packages/typespec-ts/src/modular/buildCodeModel.ts index 33e66b9d7f..7bd0c73eac 100644 --- a/packages/typespec-ts/src/modular/buildCodeModel.ts +++ b/packages/typespec-ts/src/modular/buildCodeModel.ts @@ -251,20 +251,25 @@ function getEffectiveSchemaType(program: Program, type: Model | Union): Model { return !(headerInfo || queryInfo || pathInfo || statusCodeinfo); } - let effective: Model; + // If type is an anonymous model, tries to find a named model that has the same properties + let effective: Model | undefined = undefined; if (type.kind === "Union") { const nonNullOptions = [...type.variants.values()] .map((x) => x.type) .filter((t) => !isNullType(t)); - if (nonNullOptions.length === 1 && nonNullOptions[0]?.kind === "Model") { + if ( + nonNullOptions.length === 1 && + nonNullOptions[0]?.kind === "Model" && + nonNullOptions[0]?.name === "" + ) { effective = getEffectiveModelType(program, nonNullOptions[0]); } return type as any; - } else { + } else if (type.name === "") { effective = getEffectiveModelType(program, type, isSchemaProperty); } - if (effective.name) { + if (effective?.name) { return effective; } return type as Model; diff --git a/packages/typespec-ts/src/utils/modelUtils.ts b/packages/typespec-ts/src/utils/modelUtils.ts index dd0af7ebb0..5d74c41fe4 100644 --- a/packages/typespec-ts/src/utils/modelUtils.ts +++ b/packages/typespec-ts/src/utils/modelUtils.ts @@ -229,7 +229,10 @@ export function getSchemaForType( return undefined; } export function getEffectiveModelFromType(program: Program, type: Type): Type { - // Only adopt the logic from getEffectiveModelType when it is anonymous model + /** + * If type is an anonymous model, tries to find a named model that has the same + * set of properties when non-schema properties are excluded. + */ if (type.kind === "Model" && type.name === "") { const effective = getEffectiveModelType(program, type, isSchemaProperty); if (effective.name) { diff --git a/packages/typespec-ts/test/modularUnit/type.spec.ts b/packages/typespec-ts/test/modularUnit/type.spec.ts index 6b20d5d491..11d8b1a9b6 100644 --- a/packages/typespec-ts/test/modularUnit/type.spec.ts +++ b/packages/typespec-ts/test/modularUnit/type.spec.ts @@ -18,7 +18,7 @@ describe("model type", () => { export interface Test { color: "red" | "blue"; }` - ); + ); }); it("string enum member", async () => { @@ -150,4 +150,29 @@ describe("model type", () => { ); }); }); + + describe("`is`", () => { + it("should generate correct name and properties if A is B