-
Notifications
You must be signed in to change notification settings - Fork 11
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
[BUG] Type references are not assignable with primitive types in typescript #419
Comments
Hi Andreas, thank you for your report! This only happens when the referred property in question is a key. When you remove Best, |
Hi Daniel, Yes, I do want to re-use the type of an key. Consider the following example: entity Orders : managed {
@assert.format: '^\d+$'
key ID : String(10);
// ...
}
event OrderCanceled {
orderID : Orders:ID;
// ...
}
// more events
// returns created orderIDs
action createOrder(partialOrder : PartialOrder) returns array of Orders:ID; Admittedly, I could also define the ID type explicitly, like type OrderID : String(10); and re-use it. However, the type reference approach does not require an extra type. |
Hi Andreas, just to be clear: reusing the type already works as of today, as long as you only read them: this.on('READ', FooCreated, req => {
console.log(req.data.fooName)
}) it's the assignment of a new value to this key property that throws the type system off. Manually assigning something to a Best, |
Ah, I see the problem. There are actually two use cases/problems.
Yes, consider the example above. The const order : OrdersService.Order = {
// error
ID : "0",
// ...
}
await INSERT.into(Orders).entries(order); For non-entity types, e.g. events, actions and functions, there are no key fields. In those cases, it's not relevant that the referenced type is a key, is it? Thus, there the primitive type is relevant. Consider the event example: action cancelOrder(ID : Orders:ID);
event OrderCanceled {
orderID : Orders:ID;
// ...
}
this.on("cancelOrder", req => {
const order = await SELECT.one.from(Orders).where({ID : req.data.ID});
// cancel order
const eventParams : OrdersService.OrderCanceled = {
// error
orderID : order.ID
}
await this.emit("OrderCanceled", eventParams);
}); |
Hi Andreas, thanks for elaborating! We can probably make this work, but I'd like to check back with the team first: @David-Kunz could you please let me know whether in the following case entity Orders : managed {
key ID: String(10);
}
event OrderCanceled {
orderID: Orders:ID;
} Best, |
Hi Daniel, I think we can fix the // service.cds
entity Books : cuid {}
event BookCreated {
bookId : Books:ID;
} // _/index.ts
type RemoveKeyType<T> = T extends Key<infer U> ? U : T;
export type DeepRequired<T> = {
[K in keyof T]: DeepRequired<RemoveKeyType<T[K]>>
} & Exclude<Required<T>, null>;
// service/index.ts
// event
export declare class BookCreated {
declare bookId: __.DeepRequired<Book>['ID'] | null;
} the Regards, |
Hi Ludwig, thanks for weighing in! That might be a possible approach. At the very least this can be remedied where the type reference is actually used: type Key<T> = T & { key: true }
type Unkey<T> = T extends Key<infer U> ? U : T
class Foo {
declare prop: Key<string>
}
class Bar {
declare prop: Unkey<Foo['prop']> // DeepRequired be also here
}
new Bar().prop = '42' which would not interfere with the key type elsewhere. Bottom line is: we can certainly handle this. Just making sure this is actually supposed to be this way first. 😃 Best, |
Key properties are not inherited: entity Orders : cuid {}
entity Foo { bar: Orders:ID; } console.log(cds.model.definitions['Orders'].elements.ID.key) // true
console.log(cds.model.definitions['Foo'].elements.bar.key) // false |
Thank you, David! @aschmidt93 I have prepared a fix to address this. Best, |
Hi Ludwig, thanks for trying out the fix! Scratch that, I just noticed that your recent PR in cds-types actually removed any and all use of Best, |
Change included, can be tried out now |
Looks good 👌 |
Hi Daniel, the fix seems to do the trick, thank you :) |
Hi Andreas, thanks for confirming, and also thanks Ludwig, for your suggestion and testing out the fix as well. 👍 Best, |
Is there an existing issue for this?
Nature of Your Project
TypeScript
Current Behavior
When using a type reference https://cap.cloud.sap/docs/cds/cdl#typereferences to re-use the type of a element of a entity, e.g.
String
, the generated property in TypeScript can not be assigned the respective primitive, e.g.string
.Expected Behavior
No response
Steps To Reproduce
Environment
Repository Containing a Minimal Reproducible Example
No response
Anything else?
No response
The text was updated successfully, but these errors were encountered: