- Notifications
You must be signed in to change notification settings - Fork 13.1k
Closed
Labels
Working as IntendedThe behavior described is the intended behavior; this is not a bugThe behavior described is the intended behavior; this is not a bug
Description
Currently:
function func(a: number): number; function func(a: string): string; function func(a: number | string): number | string { return 54; } const result = func("hi"); // result gets type `string`, however the // actual return type would always be `number` // (or more specifically, the literal type `54`).And:
function func(a: number): number; function func(a: string): string; function func(a: number | string): number | string { if (typeof a === "number") return "oops"; // this doesn't error else if (typeof a === "string") return 54; // nor this }There are several stages for gradually addressing this:
- Check there exists at least one code path that returns each possible return type (either a
stringor anumberin this example) or a type that's a assignable to the union of all possible return types (returning a value with typestring | numbermight work as well, although it wouldn't be really 'safe') such that the union of all actual return types at all return paths exactly matches the union of all expected return types (I might give an example to clarify what this means later). - Check that code paths where
ais narrowed tonumberalways return anumberand when narrowed tostring, always return astring(note that this check would only be reliable if the parameterais not itself reassigned with a value having an incompatible type before the runtime assertion. Unfortunately there is no current way to modify function parameters with the equivalent ofconstorreadonlyso it has to be determined based on flow analysis). - In the body of the function, infer the return type as a guarded polymorphic type that describes the relationship between parameter and return types (and possibly infer similar types to describe relationships between the parameters themselves) and even allow to defer the resolution of the return type back to the caller when the parameter given to
funcis itself a union (I'm not sure if that's currently possible, but it could be useful, see more details about how this can be achieved in the linked comment).
Metadata
Metadata
Assignees
Labels
Working as IntendedThe behavior described is the intended behavior; this is not a bugThe behavior described is the intended behavior; this is not a bug