Allow encode on a union (#2992)
fix [#2969](https://github.com/microsoft/typespec/issues/2969)
This commit is contained in:
Родитель
d8576effd5
Коммит
128a508c25
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
|
||||
changeKind: feature
|
||||
packages:
|
||||
- "@typespec/compiler"
|
||||
---
|
||||
|
||||
Enable the use of `@encode` for model properties that have a union type. This supports cases like `@encode("rfc3339") prop: utcDateTime | null`
|
|
@ -756,25 +756,20 @@ export function $encode(
|
|||
type: encodeAs ?? context.program.checker.getStdType("string"),
|
||||
};
|
||||
const targetType = getPropertyType(target);
|
||||
if (targetType.kind !== "Scalar") {
|
||||
return;
|
||||
}
|
||||
validateEncodeData(context, targetType, encodeData);
|
||||
context.program.stateMap(encodeKey).set(target, encodeData);
|
||||
}
|
||||
|
||||
function validateEncodeData(context: DecoratorContext, target: Scalar, encodeData: EncodeData) {
|
||||
function validateEncodeData(context: DecoratorContext, target: Type, encodeData: EncodeData) {
|
||||
function check(validTargets: StdTypeName[], validEncodeTypes: StdTypeName[]) {
|
||||
const checker = context.program.checker;
|
||||
const isTargetValid = validTargets.some((validTarget) => {
|
||||
return ignoreDiagnostics(
|
||||
checker.isTypeAssignableTo(
|
||||
target.projectionBase ?? target,
|
||||
checker.getStdType(validTarget),
|
||||
target
|
||||
)
|
||||
);
|
||||
});
|
||||
const isTargetValid = isTypeIn(target.projectionBase ?? target, (type) =>
|
||||
validTargets.some((validTarget) => {
|
||||
return ignoreDiagnostics(
|
||||
checker.isTypeAssignableTo(type, checker.getStdType(validTarget), target)
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
if (!isTargetValid) {
|
||||
reportDiagnostic(context.program, {
|
||||
|
|
|
@ -587,6 +587,30 @@ describe("compiler: built-in decorators", () => {
|
|||
strictEqual(getEncode(runner.program, s)?.encoding, "rfc3339");
|
||||
});
|
||||
|
||||
it(`set encoding on model property`, async () => {
|
||||
const { prop } = (await runner.compile(`
|
||||
model Foo {
|
||||
@encode("rfc3339")
|
||||
@test
|
||||
prop: utcDateTime;
|
||||
}
|
||||
`)) as { prop: ModelProperty };
|
||||
|
||||
strictEqual(getEncode(runner.program, prop)?.encoding, "rfc3339");
|
||||
});
|
||||
|
||||
it(`set encoding on model property of union type`, async () => {
|
||||
const { prop } = (await runner.compile(`
|
||||
model Foo {
|
||||
@encode("rfc3339")
|
||||
@test
|
||||
prop: utcDateTime | null;
|
||||
}
|
||||
`)) as { prop: ModelProperty };
|
||||
|
||||
strictEqual(getEncode(runner.program, prop)?.encoding, "rfc3339");
|
||||
});
|
||||
|
||||
it(`encode type default to string`, async () => {
|
||||
const { s } = (await runner.compile(`
|
||||
@encode("rfc3339")
|
||||
|
|
Загрузка…
Ссылка в новой задаче