Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

normalize-name-in-interface-and-type-alias #2483

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions packages/typespec-ts/src/modular/buildCodeModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ function processModelProperties(
// because it's impossible to have a anonymous model as the polymorphic base in typespec
// the only possibility is the anonymous model is an alias for an union type which has already been taken care of in the combined types.
if (newValue.name) {
newValue.name = normalizeName(newValue.name, NameType.Interface);
discriminatorInfo?.aliases.push(`${newValue.name}`);
newValue.alias = `${newValue.name}`;
newValue.name = `${newValue.name}Union`;
Expand Down Expand Up @@ -1108,9 +1109,10 @@ function emitEnum(context: SdkContext, type: Enum): Record<string, any> {

return {
type: "enum",
name: getLibraryName(context, type)
? getLibraryName(context, type)
: type.name,
name: normalizeName(
MaryGao marked this conversation as resolved.
Show resolved Hide resolved
getLibraryName(context, type) ? getLibraryName(context, type) : type.name,
NameType.Interface
),
description: getDocStr(program, type),
valueType: { type: enumMemberType(type.members.values().next().value) },
values: enumValues,
Expand Down Expand Up @@ -1399,10 +1401,13 @@ function emitUnion(
}
return valueType;
});
const unionTypeName = unionName
? normalizeName(unionName, NameType.Interface)
: undefined;
return {
nullable: sdkType.nullable,
name: unionName,
description: `Type of ${unionName}`,
name: unionTypeName,
description: `Type of ${unionTypeName}`,
internal: true,
type: "combined",
types: variantTypes,
Expand All @@ -1417,11 +1422,14 @@ function emitUnion(
: variantTypes.map((x) => getTypeName(x).name).join(" | ")
};
} else if (sdkType.kind === "enum") {
const typeName = getLibraryName(context, type)
let typeName = getLibraryName(context, type)
? getLibraryName(context, type)
: sdkType.isGeneratedName
? type.name
: sdkType.name;
typeName = typeName
? normalizeName(typeName, NameType.Interface)
: undefined;
return {
name: typeName,
nullable: sdkType.nullable,
Expand Down
13 changes: 8 additions & 5 deletions packages/typespec-ts/src/utils/modelUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,13 @@ function getSchemaForUnion(
.map((item) => `${getTypeName(item, [SchemaContext.Output]) ?? item}`)
.join(" | ");
if (!union.expression) {
schema.name = union.name;
const unionName = union.name
? normalizeName(union.name, NameType.Interface)
: undefined;
schema.name = unionName;
schema.type = "object";
schema.typeName = union.name;
schema.outputTypeName = union.name + "Output";
schema.typeName = unionName;
schema.outputTypeName = unionName + "Output";
schema.alias = unionAlias;
schema.outputAlias = outputUnionAlias;
} else if (union.expression && !union.name) {
Expand Down Expand Up @@ -938,8 +941,8 @@ function getSchemaForEnum(dpgContext: SdkContext, e: Enum) {
const schema: any = {
type: "object",
name: e.name,
typeName: e.name,
outputTypeName: e.name + "Output",
typeName: normalizeName(e.name, NameType.Interface),
outputTypeName: normalizeName(e.name, NameType.Interface) + "Output",
description: getDoc(dpgContext.program, e),
memberType: type
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ export interface RequestRegisterCC extends CommonRegistrationRequest {
}

export interface CommonRegistrationRequest {
payMethod: PAYMENT_METHODS;
payMethod: PaymentMethods;
}

export interface RequestRegisterVA {
prop: string;
}

/** Alias for PAYMENT_METHODS */
export type PAYMENT_METHODS = "01";
/** Alias for PaymentMethods */
export type PaymentMethods = "01";
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ export interface RequestRegisterCCOutput
}

export interface CommonRegistrationRequestOutput {
payMethod: PAYMENT_METHODSOutput;
payMethod: PaymentMethodsOutput;
}

export interface RequestRegisterVAOutput {
prop: string;
}

/** Alias for PAYMENT_METHODSOutput */
export type PAYMENT_METHODSOutput = "01";
/** Alias for PaymentMethodsOutput */
export type PaymentMethodsOutput = "01";
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export interface Dog {

export interface EnumsOnlyCases {
/** This should be receive/send the left variant */
lr: LR | UD;
lr: Lr | Ud;
/** This should be receive/send the up variant */
ud: UD | UD;
ud: Ud | Ud;
}

export interface StringAndArrayCases {
Expand Down Expand Up @@ -47,7 +47,7 @@ export interface MixedTypesCases {

/** Alias for StringExtensibleNamedUnion */
export type StringExtensibleNamedUnion = string | "b" | "c";
/** Alias for LR */
export type LR = "left" | "right";
/** Alias for UD */
export type UD = "up" | "down";
/** Alias for Lr */
export type Lr = "left" | "right";
/** Alias for Ud */
export type Ud = "up" | "down";
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export interface DogOutput {

export interface EnumsOnlyCasesOutput {
/** This should be receive/send the left variant */
lr: LROutput | UDOutput;
lr: LrOutput | UdOutput;
/** This should be receive/send the up variant */
ud: UDOutput | UDOutput;
ud: UdOutput | UdOutput;
}

export interface StringAndArrayCasesOutput {
Expand Down Expand Up @@ -47,7 +47,7 @@ export interface MixedTypesCasesOutput {

/** Alias for StringExtensibleNamedUnionOutput */
export type StringExtensibleNamedUnionOutput = string | "b" | "c";
/** Alias for LROutput */
export type LROutput = "left" | "right";
/** Alias for UDOutput */
export type UDOutput = "up" | "down";
/** Alias for LrOutput */
export type LrOutput = "left" | "right";
/** Alias for UdOutput */
export type UdOutput = "up" | "down";
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export {
MixedLiteralsCases,
StringAndArrayCases,
EnumsOnlyCases,
LR,
UD,
Lr,
Ud,
Dog,
StringExtensibleNamedUnion,
StringsOnlyGetOptionalParams,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export {
MixedLiteralsCases,
StringAndArrayCases,
EnumsOnlyCases,
LR,
UD,
Lr,
Ud,
Dog,
StringExtensibleNamedUnion,
} from "./models.js";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ export interface StringAndArrayCases {

export interface EnumsOnlyCases {
/** This should be receive/send the left variant */
lr: LR | UD;
lr: Lr | Ud;
/** This should be receive/send the up variant */
ud: UD | UD;
ud: Ud | Ud;
}

/** */
export type LR = "left" | "right";
export type Lr = "left" | "right";
/** */
export type UD = "up" | "down";
export type Ud = "up" | "down";

export interface Dog {
bark: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export interface Dog {

export interface EnumsOnlyCases {
/** This should be receive/send the left variant */
lr: LR | UD;
lr: Lr | Ud;
/** This should be receive/send the up variant */
ud: UD | UD;
ud: Ud | Ud;
}

export interface StringAndArrayCases {
Expand Down Expand Up @@ -47,7 +47,7 @@ export interface MixedTypesCases {

/** Alias for StringExtensibleNamedUnion */
export type StringExtensibleNamedUnion = string | "b" | "c";
/** Alias for LR */
export type LR = "left" | "right";
/** Alias for UD */
export type UD = "up" | "down";
/** Alias for Lr */
export type Lr = "left" | "right";
/** Alias for Ud */
export type Ud = "up" | "down";
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export interface DogOutput {

export interface EnumsOnlyCasesOutput {
/** This should be receive/send the left variant */
lr: LROutput | UDOutput;
lr: LrOutput | UdOutput;
/** This should be receive/send the up variant */
ud: UDOutput | UDOutput;
ud: UdOutput | UdOutput;
}

export interface StringAndArrayCasesOutput {
Expand Down Expand Up @@ -47,7 +47,7 @@ export interface MixedTypesCasesOutput {

/** Alias for StringExtensibleNamedUnionOutput */
export type StringExtensibleNamedUnionOutput = string | "b" | "c";
/** Alias for LROutput */
export type LROutput = "left" | "right";
/** Alias for UDOutput */
export type UDOutput = "up" | "down";
/** Alias for LrOutput */
export type LrOutput = "left" | "right";
/** Alias for UdOutput */
export type UdOutput = "up" | "down";
37 changes: 34 additions & 3 deletions packages/typespec-ts/test/modularUnit/enumUnion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -842,17 +842,48 @@ describe("model type", () => {
modelFile!.getFullText()!,
`
export interface Test {
color: LR | UD;
color: Lr | Ud;
qiaozha marked this conversation as resolved.
Show resolved Hide resolved
}

/** */
export type LR = "left" | "right";
export type Lr = "left" | "right";
/** */
export type UD = "up" | "down";
export type Ud = "up" | "down";
`
);
});
it("non standard enum name", async () => {
qiaozha marked this conversation as resolved.
Show resolved Hide resolved
const modelFile = await emitModularModelsFromTypeSpec(`
union leftAndRight {
"left",
"right",
}
enum upAndDown {
up,
down,
}

model Test {
color: leftAndRight | upAndDown;
}
op read(@body body: Test): void;
`);
assert.ok(modelFile);
await assertEqualContent(
modelFile!.getFullText()!,
`
export interface Test {
color: LeftAndRight | UpAndDown;
}

/** Type of LeftAndRight */
/** */
export type LeftAndRight = "left" | "right";
/** */
export type UpAndDown = "up" | "down";
`
);
});
it("nullable numeric literal", async () => {
const modelFile = await emitModularModelsFromTypeSpec(`
model Test {
Expand Down
64 changes: 64 additions & 0 deletions packages/typespec-ts/test/unit/modelsGenerator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,49 @@ describe("Input/output model type", () => {
export type TranslationLanguageValuesOutput = "English" | "Chinese";`
);
});
it("should handle enum with non-standard name as property -> type alias with union", async () => {
const schemaOutput = await emitModelsFromTypeSpec(`
@doc("Extensible enum model description")
enum translationLanguageValues {
#suppress "@azure-tools/typespec-azure-core/documentation-required" "for test"
English,
#suppress "@azure-tools/typespec-azure-core/documentation-required" "for test"
Chinese,
}
model InputOutputModel {
@doc("Property description")
prop: translationLanguageValues;
}
@route("/models")
@get
op getModel(@body input: InputOutputModel): InputOutputModel;
`);
assert.ok(schemaOutput);
const { inputModelFile, outputModelFile } = schemaOutput!;
await assertEqualContent(
inputModelFile?.content!,
`
export interface InputOutputModel {
/** Property description */
prop: TranslationLanguageValues;
}
/** Extensible enum model description */
export type TranslationLanguageValues = "English" | "Chinese";
`
);
await assertEqualContent(
outputModelFile?.content!,
`
export interface InputOutputModelOutput {
/** Property description */
prop: TranslationLanguageValuesOutput;
}
/** Extensible enum model description */
export type TranslationLanguageValuesOutput = "English" | "Chinese";`
);
});
it("should handle enum as body -> type alias with union", async () => {
const schemaOutput = await emitParameterFromTypeSpec(`
#suppress "@azure-tools/typespec-azure-core/documentation-required" "for test"
Expand Down Expand Up @@ -2282,6 +2325,27 @@ describe("Input/output model type", () => {
});
});

it("union with non-standard name whose variants are pure primitive types", async () => {
const tspDefinition = `
union myNamedUnion {
one: string,
two: int32,
}
`;
const tspType = "myNamedUnion | null";
const inputModelName = "MyNamedUnion | null";
await verifyPropertyType(tspType, inputModelName, {
additionalTypeSpecDefinition: tspDefinition,
outputType: `MyNamedUnionOutput | null`,
additionalInputContent: `
/** Alias for MyNamedUnion */
export type MyNamedUnion = string | number;`,
additionalOutputContent: `
/** Alias for MyNamedUnionOutput */
export type MyNamedUnionOutput = string | number;`
});
});

it("union variants are pure constants", async () => {
const tspDefinition = `
union StringExtensibleNamedUnion {
Expand Down
Loading