-
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
Allow function overloads with a varying parameter to unify, and inductively narrow the parameter when narrowing the return type #12885
Comments
Yeah...I've picked up a few things on how partial types, readonly types, Oh, and this also would fix these two (among likely others):
If type unions of functions are similarly unified, this would also fix #10620 (among likely others). Similar induction with objects would also fix #12448, but that's beyond the scope of this proposal. |
Duplicate #7294 ? |
I believe these are two issues. 1. issues like In DefinitelyTyped, we have added a tslint rule to flag these cases as an error (see unifiedSignaturesRule). We could incorporate this into the compiler, and make it an error to have two signatures vary only by the type of one paramter, but this would be a breaking change. |
just to clarify what i meant: interface AcceptsStringAndNumber {
push(a: string): void;
push(a: number): void;
}
interface AcceptsString {
push(a: string): void;
}
interface AcceptsNumber {
push(a: number): void;
}
type AcceptsStringOrNumber = AcceptsString | AcceptsNumber;
var value: string | number;
var acceptsStringAndNumber: AcceptsStringAndNumber;
acceptsStringAndNumber.push(value); // Safe, but not allowed
var acceptsStringOrNumber: AcceptsStringOrNumber;
acceptsStringOrNumber.push(value); // Unsafe, and not allowed |
Yes, that is the correct understanding of the current state. In particular,
I'm proposing the safe one to be unified, not the unsafe one.
(This is mod the return type half, which is much more complex)
…On Wed, Dec 14, 2016, 18:09 Mohamed Hegazy ***@***.***> wrote:
just to clarify what i meant:
interface AcceptsStringAndNumber {
push(a: string): void;
push(a: number): void;
}
interface AcceptsString {
push(a: string): void;
}
interface AcceptsNumber {
push(a: number): void;
}
type AcceptsStringOrNumber = AcceptsString | AcceptsNumber;
var value: string | number;
var acceptsStringAndNumber: AcceptsStringAndNumber;acceptsStringAndNumber.push(value); // Safe, but not allowed
var acceptsStringOrNumber: AcceptsStringOrNumber;acceptsStringOrNumber.push(value); // Unsafe, and not allowed
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#12885 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AERrBKiOF8R0PbxFVio-r3Tar-DoP78aks5rIHc5gaJpZM4LL5ym>
.
|
To clarify the return type half and its related inference, it's this: declare const stringOrNumber: string | number;
declare function convert(s: string): string;
declare function convert(n: number): number;
const result = convert(stringOrNumber);
if (typeof result === "string") {
// stringOrNumber is type `string` here
} else {
// stringOrNumber is type `number` here
} |
related: #6160 |
Closing in favor of #13257, since that is a better thought out, more general superset of this. |
I don't really know how to word the title for this one or explain it well...but here's what I'm thinking: it would be nice to allow function overloads to unify, provided only one parameter and possibly the return type are different across each overload. Additionally, when narrowing the returned type, it should be able to inductively narrow the overloaded parameter's type accordingly within the same block. To hopefully explain this a little better, here's what I mean:
In this case, if
result
is aFoo
,str
can only possibly be a"foo"
through induction, and similarlyresult
being aBar
andstr
being a"bar"
.With #12883 also, this would also permit assertions to do compile-time type narrowing, without adding any new syntax or special casing of any particular identifier, hence fixing #12825 and #8655 simultaneously while remaining much more flexible:
I know this would likely be really hard to implement, but it would pay off. It helps that
boolean
is equivalent totrue | false
,"foo"
is a subtype ofstring
,E
is equivalent toE.A | E.B | E.C
whereenum E {A, B, C}
, etc., so much of the structural narrowing would allow this to apply to several other areas.Note that this would specifically not allow more than one varying type to be unified, because it would be an M⨯N type implication, which would be unrealistic to infer in practice (you would already need
length
to be similarly guarded in theory):Sorry if I did a really poor job explaining it (I don't really know the correct technical term for this, hence the detailed examples).
The text was updated successfully, but these errors were encountered: