-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Allow narrowing type based on others properties when creating a new object #37224
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
Comments
This is a particular use case of #12184 and similar to one of the motivating examples I had for #25051 (see this comment). It seems that the suggestion here is that whenever a new object literal is created, the compiler should check to see if any union-typed value is mentioned multiple times, and then automatically distribute the control flow analysis over the different narrowings of that value. So if you have the following: declare const x: A | B | C;
declare const f: <T>(t: T) => F<T>;
const obj = {x: x, fx: f(x)}; you'd want the compiler to notice that I would love it if such things could happen automatically but I expect that the performance impact would be prohibitive, especially given the potential combinatoric nightmare of things like In my fantasy world (aka #25051) I'd want to be able to manually ask the compiler to do such analysis so as to get this benefit while preserving the normal behavior and performance for normal code. In your case it would look something like example({
kind: nameOrAge,
value: (nameOrAge === 'name' ? 'macabeus' : 23),
} as if switch(nameOrAge)) Oh well! :wistful-sigh: |
@jcalz Thank you for reply!
Yeah. The idea on this proposal is only when creating a new object literally, in order to avoid problems on performances and to be easer to implement.
I don't know if is really necessary to automatically distribute for each value on the enum. For example, on this case is necessary to distribute just two times: let nameOrSomething: 'name' | 'age' | 'height' | 'money'
example({
kind: nameOrSomething,
value: (nameOrSomething === 'name' ? 'macabeus' : 20),
}) Just need to check:
Are you looking other case that will demand to do more checks? |
The existence of tractable cases doesn't imply that combinatorially-explosive cases don't still exist. The algorithm can't be "look for the one comparison of the discriminant and then do the right thing". If you wrote something like let nameOrSomething: 'name' | 'age' | 'height' | 'money' | (30 other values)
example({
kind1: nameOrSomething,
kind2: nameOrSomething === "age" ? "age2" : nameOrSomething,
value: (nameOrSomething === 'name' ? 'macabeus' : 20),
value1: (nameOrSomething === 'age' ? nameOrSomething : 20),
value2: (nameOrSomething === 'height' ? 'macabeus' : 20),
value3: (nameOrSomething === 'money' ? 'macabeus' : nameOrSomething),
value4: (nameOrSomething !== 'age' ? 'macabeus' : 20),
value5: (nameOrSomething === 'money' && nameOrSomething === 'age' ? 'macabeus' : 20)
}) and then compared that to some complex definition of |
Search Terms
Suggestion
Currently, TypeScript isn't narrowing the type based on others properties that is defined while creating a new object. For example. Let's say the we have the following function:
So we can call it using codes like:
But isn't possible to compile code like:
Playground
but we know that, if
nameOrAge
is'name'
, the propertyvalue
will be a string, otherwisenameOrAge
will be'age'
andvalue
will be23
- that is correct.I think that would be useful if TS could check this behaviour.
Use Cases
It would be useful to reduce the amount of code on situations like described on the above section.
Currently, is necessary to write more lines to have the same behaviour:
Playground
Related
I know that there are a lot of issues saying about narrowing types based on variables, such as:
But here I'm saying only about when is creating a new object, and as far as I know is a simpler case if compared on these others issues, since doesn't need to track the entire code base.
On the case that I'm saying, TS just need to check the others properties defined on the same object and if the variable name already is used. For example, TS doesn't need to change its behaviour on this case:
Probably it isn't the best solution, but I think that it follow the Pareto efficiency.
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: