-
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
Generic constraints as return type in class methods #35077
Comments
The error here is correct.
It satisfies the constraint, yes, but it doesn't satisfy all possible types that |
Here's a concrete example of the kind of error TS is trying to protect you from, export class Model<GenericSchema extends { id: string }> {
public fails(): GenericSchema {
return { id: '' }; // <-- This line produce the error, see below
}
public works(): GenericSchema {
return { id: '' } as GenericSchema;
}
}
const model = new Model<{id:string, x:string}>();
const obj = model.works();
console.log(obj.x); //undefined, but supposed to be string, right? |
Thanks a lot for the example, that makes a lot of sense! In my real use case I'm accessing a database so it would be OK for Now, if I change the example to be a bit closer to a real use case with an external db driver module, it may look something like this. And now the compiler accepts the generic as a return type, without the type assertion - which also makes sense. // TS don't know what's in the DB (obviously)
const dataInDb: any = {id: '', stuff: ''}
// DB Driver takes a generic which defines what is
// in the DB (up to the developer to make sure the
// generic match the data model)
function readDb<Schema>():Schema {
return dataInDb
}
class Model<Schema extends { id: string }> {
// This now works without the type assertion
public read(): Schema {
return readDb<Schema>();
}
}
const model = new Model<{id:string, x:string}>();
const obj = model.read();
console.log(obj.x); //undefined A more contrived example: class Model<GenericSchema extends { id: string }> {
public fails(): GenericSchema {
return { id: '' } as any; // <-- This line does not produce any error anymore
}
public works(): GenericSchema {
return { id: '' } as GenericSchema;
}
}
const model = new Model<{id:string, x:string}>();
const obj = model.works();
console.log(obj.x); //undefined In summary, my initial example was simply not correct and both examples works as expected. I'll close this issue and bring the matter back over to the Big thanks for your help @fatcerberus and @AnyhowStep! |
TypeScript Version: 3.6.4 & 3.7.2 & 3.8.0-dev.20191112
Search Terms: generic constraints, TS2322, 2322
Code
Expected behavior:
Should compile without errors. To me this should work since the the
fails()
method returns an object which satisfies the constraint{ id: string }
.Actual behavior:
Context:
For additional context, I originally filed an issue with
@types/mongodb
which gives the original use caseDefinitelyTyped/DefinitelyTyped#39358
Last, here is a discussion of the exact same matter on Stack Overflow
https://stackoverflow.com/questions/58663733/typescript-class-generic-constraint
Playground Link:
https://codesandbox.io/s/mapped-type-with-generics-l4b0b
Related Issues:
I believe this is related to #34567 and as such probably also #33014.
The text was updated successfully, but these errors were encountered: