-
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
Weird type inference / defaulting behavior #11112
Comments
This is correct behavior. To understand why lets consider the declaration declare class Maybe<T> {
static nothing<T>(): Maybe<T>;
valueOrThrow(error?: Error): T;
} This declares a type Maybe<T> = {
valueOrThrow(error?: Error): T;
};
type MaybeConstructor = {
new<T>(): Maybe<T>;
nothing<T>(): Maybe<T>;
};
declare let Maybe: MaybeConstructor; Note where the type arguments appear in the decomposition above.
a. The generic type b. The value Maybe which has the the non generic type In summary, Maybe refers to the value EDIT: muchAdoAbout(Maybe.nothing<string>()); |
I agree with @aluanhaddad it's correct behaviour. I think it's even simpler to explain. With the But with the |
@yortus that is indeed true. I was being extra specific because I believe the OP intended for there to be an instance member but had commented it out in the course of trial and error debugging. |
@aluanhaddad fair enough. @Ptival note that |
Hmmm I'm still not quite convinced. What makes this work until you uncomment one of the three lines? declare class Beep<T> { beepField: string }
declare class Boop<T> { boopField: T }
declare class Maybe<T> {
static nothing<T>(): Maybe<T>
foo(t: T): any // fine as a parameter
bar(): Maybe<T> // fine in some return types
beep: Beep<T> // fine in some return types
// bad: T // bad
// baz: T[] // bad
// boop: Boop<T> // bad
}
function muchAdoAbout(m: Maybe<string>): void { }
muchAdoAbout(Maybe.nothing()) It seems that it matters in what position/variance |
@Ptival This goes back to @yortus's remark
Note that declare class Beep<T> { beepField: string } does not use its type argument but declare class Boop<T> { boopField: T } does. declare class Maybe<T> {
static nothing<T>(): Maybe<T>;
getValue (): T; // error
setValue(x: T): any; // not an error
}
function muchAdoAbout(m: Maybe<string>): void {
m.setValue("abc");
}
muchAdoAbout(Maybe.nothing()); It is a little more complicated. Having |
TypeScript Version: nightly (2.1.0-dev.20160915)
Code
Expected behavior:
When the commented out line is uncommented, the code should still type-check (the
nothing
on the last line should get its type found to bestring
by use-site inference like it does already).Actual behavior:
When you uncomment the
valueOrThrow
line, the type inferred at the call site becomes{}
and the code does not type-check anymore.I'm not sure why adding that line has this effect. Note that it works if you do instead:
// valueOrThrow<T>(error?: Error): T;
But I'd like to understand if the behavior shown here is a bug or intended...
Not sure if related to:
#5254
The text was updated successfully, but these errors were encountered: