-
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 setter type to be incompatible with the getter type #43662
Comments
In the "Restrictions" section near the top of #42425, Ryan said that "
Also, in case it matters, |
Why not just make a Get..() and Set...() function? Getters and setters are supposed to be so simple that they are similar in use as fields. |
That should still be a static error because it's virtually |
I mean, it will literally never do what you want or expect, unless you just want to watch the |
Lending my support to this proposal. Thankfully language ability trumps subjective opinion. If we wanted to write a bunch of |
Hi y'all, I'd like +1 this proposal as well. In Relay (relay.dev), we are working on a feature where graphql linked fields can be updated with simple assignment, instead of the ugly existing API
This allows us to enforce that any user that can be assigned to (This is only part of what is required to ensure that the assignment is valid, but the rest is irrelevant for the getter/setter discussion.) Thank you! It would be a pity to be able to roll this out with full type safety for users of Flow, but to have limited type safety in Typescript. |
+1 to this proposal. Using apollo + graphql on front end. And such functionality would be really VERY helpful.
Though I am using Javascript Proxy API and it will work in both cases(with get and set) with corresponding types. |
+1 for this feature. Flagging this issue that contains lots of great use cases for incompatible getter/setter types: #2521 |
Just wanted to flag another Web API that isn't able to be used without this feature: The URL.search getter returns const url = new URL("https://example.com");
url.search = new URLSearchParams({ test: "test" }); with |
Your code is equivalent to this: const url = new URL("https://example.com");
url.search = new URLSearchParams({ test: "test" }).toString(); ... as URLSearchParams has special stringification behavior. So no, it can be used without this feature. |
I feel like the pot holes generated by having different get/set types can also be overcome by TypeScript. I believe most people are going to support same types and over load them to be different as well for example get id(): string {}
set id(): string | number {}
Edit: This argument is invalid. This is the default behavior. |
* removing guard as console.warn is now widely supported * Couldn't remove non-null assertion, waiting for TS support of getters with different types (microsoft/TypeScript#43662)
* removing guard as console.warn is now widely supported * Couldn't remove non-null assertion, waiting for TS support of getters with different types (microsoft/TypeScript#43662)
* removing guard as console.warn is now widely supported * Couldn't remove non-null assertion, waiting for TS support of getters with different types (microsoft/TypeScript#43662)
* removing guard as console.warn is now widely supported * Couldn't remove non-null assertion, waiting for TS support of getters with different types (microsoft/TypeScript#43662)
* removing guard as console.warn is now widely supported * Couldn't remove non-null assertion, waiting for TS support of getters with different types (microsoft/TypeScript#43662)
* removing guard as console.warn is now widely supported * Couldn't remove non-null assertion, waiting for TS support of getters with different types (microsoft/TypeScript#43662)
* removing guard as console.warn is now widely supported * Couldn't remove non-null assertion, waiting for TS support of getters with different types (microsoft/TypeScript#43662) PR Close #48476
* removing guard as console.warn is now widely supported * Couldn't remove non-null assertion, waiting for TS support of getters with different types (microsoft/TypeScript#43662) PR Close #48476
* removing guard as console.warn is now widely supported * Couldn't remove non-null assertion, waiting for TS support of getters with different types (microsoft/TypeScript#43662) PR Close #48476
What are the blockers for making this happen? The error when this rule is violated seems like a nice-to-have, but when the narrowing is intentional it is paralyzing. If the feeling is that this loosening deserves some positive indication from the developer, one could have the set declaration take a generic:
this works even if you don't want to define a getter:
|
Just spent an hour debugging an error caused by a junior dev that never would have existed if TypeScript could recognize getter-less properties as such. Would be great if this issue were prioritized. |
Maxim, I think you're having a slightly different issue. You want this linter rule which prevents the creation of setter-only properties. I think there might actually be an issue on this tracker about it, but under the hood this is basically a problem of bad JS/ES design, and TS is kind of stuck with it. |
@MaximSagan Or you can just scream at the junior dev for not making it an idiomatic |
I think Maxim's point was that if getters and setters were allowed to be incompatible, then the missing getter could be typed, whether explicitly or implicitly, as For now, we have that linter rule. |
* removing guard as console.warn is now widely supported * Couldn't remove non-null assertion, waiting for TS support of getters with different types (microsoft/TypeScript#43662) PR Close angular#48476
A periodic reminder to the TS staff that the community has been asking for this since 2015 (#2521). |
I actually brought this up a few weeks ago and we agreed itβs worth some experimenting during 5.1. I just forgot to update the issue afterwards; thanks for the reminder. To be fair though, #2521 is closed because #42425 was thought to address it. This issue was raised afterwards to present use cases that #42425 did not address. |
Perhaps a unique use case, but I'll log mine here. I wanted to allow providing an update function to pass to Immer in addition to just setting the new value. This works fine in JS, but I can't get the Type definitions to comply console.log(someObj.profile) // { name: 'John Doe' }
someObj.profile = { name: 'This works' }
someObj.profile = (draft) => {
draft.name = 'This does not'
} |
use case: getter/setter in mapped type for proxy value with different types for reactive (rxjs like) api I have Proxy object, that simplifies api for rxjs like values Example code: values: MyProxy<{ x: number, y: number }>;
values.x = 10;
values.y = () => values.x + 10;
const finalY = values.y; Type of Proxy here should be: {
get [K in keyof T](): T[K];
set [K in keyof T](value: T[K] | (() => T[K]));
} Not found any hacks/workarounds here, because mapping object with get/set captures only getter's type: {
[k in keyof T]: {
get x(): T[k];
set x(val: T[k] | (() => T[k]));
}["x"];
}
// results in
{
[k in keyof T]: T[k]
} Actually typescript should add 'set' modifier for fields along with eg 'readonly'; Which should work same way and check assigment type: type T;
type T_add_set = {
set [k in keyof T]: T[k] | (() => T[k])
}
type T_remove_set = {
-set [k in keyof T_add_set]: T_add_set[k]
} And 'get' modifier is just 'readonly' which will be resolved similar to function overloading (if 'readonly' and 'set' presents for same field) |
Thank you! |
Suggestion
π Search Terms
differing accessor types
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
#42425 forces the getter type to be assignable to the setter type. This makes the feature limited on the following DOM typing case, and thus it could be great if the limitation can be lifted.
π Motivating Example
π» Use Cases
Allows Web IDL readonly attributes to be assignable, and thus the DOM typing better matches the actual behavior.
Transferred from microsoft/TypeScript-DOM-lib-generator#996.
The text was updated successfully, but these errors were encountered: