-
-
Notifications
You must be signed in to change notification settings - Fork 76
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
Support strict true, AsObject and AsObjectPartial types #159
Conversation
Removed RecursivePartial<T>, instead introduced AsObjectPartial, which is used as fromObject method argument. Make getters, setters and AsObject typed according to canHaveNullValue predicate. Brought AsObjectPartial into line with constructor's declaration.
Sorry for the weeks-taking review. I hope this is not blocking you. I have a few concerns about this PR; 1- I am not a huge fan of the synthetic 2- Partial type. Suffers from the same problem with number one. Which also I think unnecessary. I believe something like Perhaps, the need for these subtypes signals that we have missing type information in our getters and setters? |
Hey, I understand your concerns, but I think we can avoid breaking code in the future by using aliases. export namespace MessageType {
export type AsObject = {};
export type NewAsObjectName = AsObject;
} Yeah, removal is a breaking change. And I see you are against the possibility of this. Let me explain why do we may need these subtypes. In frontend applications it is common to use plain objects and some libraries even require that. For instance, Redux highly recommends using only plain objects, 58k starts on Github, as well as NgRx, 7.3k starts on Github. So in frontend applications, we usually convert proto into a plain object just after receiving and convert back to proto just before sending. Of course, we can use types like While Of course, the decision is for you, but I would be happy if there were
Yeah, that was my initial idea. I have introduced a type RecursivePartial<T> = {
[P in keyof T]?:
T[P] extends (infer U)[] ? RecursivePartial<U>[] :
T[P] extends Uint8Array ? T[P] :
T[P] extends object ? RecursivePartial<T[P]> :
T[P];
}; But there was a problem with maps. There is no way to determine if the field is a map or a submessage on the type level and map type turns into
I haven't faced such problems. There is only a mismatch of the type nullability with the actual value nullability, which is fixed in this PR. |
Two things that I don't want to continue having.
what if when you do |
Fair enough.
No, I need a named type to use it for typing Angular component's input properties and function arguments. // This is a class linked to the template referenced in my previous message
export class MenuItemCardComponent {
@Input() menuItem!: MenuItemObj;
} I agree to inline export abstract class Message {
// ...
abstract toObject(includeInstance?: boolean): {};
// ...
} When I rename method to be I suggest adding a new method, called toObjectTyped() {
return this.toObject();
} Maybe we can have inline types and a compiler option to generate and export types like |
Still couldn't spare time to think about this thoroughly.
this is what we've been doing so far. I'd be fine with inline types until we solve it. the ideal solution would be fixing https://github.com/DefinitelyTyped/DefinitelyTyped/blob/3407f3a072abbab47a7ad706c15f69d6b7926577/types/google-protobuf/index.d.ts#L128 to be |
Related to #154
Tsconfig option
strict
is enabled in all tests. All tests extend base tsconfig.json in thetest
dir.toObject
method now returnsAsObject
type declared inside a message namespace.fromObject
now acceptsAsObjectPartial
type, that has as many nullable fields as possible, in contrast toAsObject
.These types are useful when dealing with plain objects, which is common in frontend applications.
The return type of the
toObject
method (AsObject
) determines if the field is nullable by using this function:These functions have been derived after some discussion in #146 (link to the comment).
Getter and setter types changed, but this will only affect the
strict:true
users of typescript.The function above is also responsible for getter and setter type nullability.