-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Omitting generics from the end is not allowed #3448
Comments
The compiler can not know the intention. so either you left it off by mistake or intentionally to mean |
It's not artificial example, I'm creating a validator and it requires me to type both generics even though the second one is always much better as type inferred. It's hard to explain this succintly, but I suspect there is whole lot of other use cases for leaving rest of the generics for type inference. Did you look at this edit I added: the intentional syntax |
Could you post an example of code where you need to explicitly specify some type arguments which aren't inferred correctly while others are? The better fix from my perspective would be to fix the inference process so that you don't have to specify any of the type arguments explicitly. |
This example would be prohibitively long, so I'll try again with use case. But the use case is so cool and useful that I really want this to work! This is basically Django class fields syntax as object literal, and with interfaces, no classes was abused! It allowes to create nested validator in fully readable format, check this out: interface Address {
city : string
street : string
}
interface User {
id: number
name: string
email: string
address: Address
}
var userValidator = V.objectField<User>({ // Here is the GIST of the problem!
id : V.integerField(),
name : V.stringField(required=true),
email : V.stringField(),
address : V.objectField<Address>({
city : V.stringField(),
street : V.stringField(),
})
});
userValidator
.validate({...}) // Some User object from FORM data etc. you want to validate
.then(function (valid) {
// Valid is User!
})
.catch(function (errors) { // errors is {[name: string} : string[]}
});
// Or I can fully typedly validate part of the tree:
userValidator.$.address
.validate({...}) // Address
.then(function (valid) {
// Valid is Address!
})
.catch(function (errors) { // errors is {[name: string} : string[]}
});
// or nested
userValidator.$.address.$.street.validate(...) // This *is* same stringField as in the definition Get it? The The use case I have here is really amazing! Unfortunately to get this thing working right now I have to write it something like this :(
Because if I put that Edit IF you are wondering why the second generic is there at all it's because it has important use cases. E.g. I have special variable $ I have added it's use case to above example. |
looks like this is a dupe of #3423 then? |
In my case the User is not inferrable from anywhere, it's tight to the validator object when validator is defined. I mean this:
Can't be simplified anymore in any way. It already contains everything it needs to. This "User" can't be inferred from anywhere. Because the above syntax defines the validator for But I do agree however that maybe optional generics is not a good thing and I propose either alternative syntax:
|
Edit I must say this is a hack, and not a real solution. It is awful to use, I've tried really hard. I just discovered a way to "omit" generics using a function, that returns a function: // Trick is the definition in here:
function objectField<C>(v: C): <M>() => ObjectField<M, C> {
return <any> null; // This implementation is not relevant
}
// Now I can define it neatly as two, with this first one type inferred, and second one as typed
var validator = V.objectField({
id : V.numberField(),
name : V.stringField(),
addresses : V.arrayField(V.objectField({
id : V.numberField(),
street : V.stringField(),
city : V.stringField()
}))
})<{
id : number,
name : string,
addresses : {
id : number,
street : string,
city : string
}[]
}>();
validator.$.id // Auto completes as id, numberField
validator.validate(<any>{}).then(v => {
v.id // Auto completes as id, number
}); |
#2175 provides a safer way to achieve the desired output. the declarations will need to opt-in into this by specifying a default type. |
I don't see why omitting (or leaving remaining generics for type inference) is not allowed:
Now this is trivial in case of string, but if the argument is something like object literal, then I have to retype everything from that object literal to two places.
Another syntax proposal could be allowing have empty comma, like this:
test<Thingie,>("test");
It would signify that second parameter is left empty, intentionally.
The text was updated successfully, but these errors were encountered: