-
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
maintain certain class property characteristics in mapped types, like protected/private visibility, and instance property vs instance function #35416
Comments
I'm aware that we can use class-factory mixins, but they are more complex and harder to use than my
On the other hand, for the end user, using
This totally decouples class composability from class implementation, with the only needed boilerplate for composition being a call to I'd love to make this a reality, but I haven't made a code contribution to TypeScript yet, and do not know the TS source yet). I'm interested in implementing this, but I want to wait to see if the team thinks it may be feasible, so that I won't spend time before knowing if the team thinks it is feasible. One thought I had is to always keep property characteristics inside of mapped types (keep protected/private members, keep instance member functions as instance member functions, etc), then if the type is passed into the |
@kitsonk You mentioned here that
I currently have this issue with the above At the moment, anyone using my |
@RyanCavanaugh What sort of more feedback would you like? I think my examples covered all the details. I have a real working |
cc people with thoughts and work in this general area of mixins (multiple inheritance): @canonic-epicure @justinfagnani @tannerntannern |
@trusktr, it's not entirely clear to me what you're looking for based on this thread, but I believe the typing you want for multiple inheritance for can already be achieved without changes to TypeScript's internals. |
@tannerntannern If that's the case, how would we fix the above playground examples? In particular this one. I thought there to be no solution. |
Here's an example showing a way to make it work without mapped types. I made 9 overloads of the With mapped types, there would be no limit, but it erases the types. Did I miss some other way to do it? |
@MicahZoltu just showed me how to do it with tuple-to-union-to-intersection. Amazing. Playground Example. |
I'm re-opening this, because the problem still persists with mapped typed specifically. Any time we run something like One key issue caused by this is that it makes working with mixins and other class-programming concepts more difficult. In the previous comment's playground example, it works, except that if two classes have the same property but with differing types then the outcome type will be Here is a playground example that shows how the At runtime (in plain JS) the However in TypeScript, there's no way to pluck the first property (with mapped types) without losing Here's the same example but using the original It seems that if we wish to "pick the type of the first property in the collision", we have to use mapped types, and in such case we can not use For example, here's a playground example that shows the accidental overriding of a private property, which may break the application. Going back to the tuple-based approach, here's that same example with a Here is a playground example that shows my preferred approach (for now), which is to use Finally, note that ES |
i have similar issue here where some pattern make complications ! type Writable<T> = { -readonly [P in keyof T]: T[P] }; // make writable A.parent for Childrable
class A {
public readonly parent?: A
protected Renderer() { }
}
class Childrable {
public entity!: A;
public readonly children: A[] = [];
public addChild(...children: Writable<A>[]) {
if (children.length > 1) {
for (const child of children) this.addChild(child);
} else {
const child = children[0];
if (child) {
// So Writable<A> allow replace A.parent
child.parent = this.entity;
// But Writable<A> seem remove protected.Renderer prototype and now they are not compatible
// I need allow replace A.parent and add A in Childrable.children in the same scope !
this.children.push(child);
}
}
return this;
}
} It would be great to see easy way to handle more pattern with protected, private fields when we map types for specific case |
To participate, my suggest will be to ask for add a new utility called type Writable<T> = { -readonly [P in fieldof T]: T[P] }; So same as |
Search Terms
mapped types with protected private members
Suggestion
Feature request:
Allow types/interfaces to contain member visibility as well as property type ("instance member function" vs "instance member property") and perhaps other intrinsics.
Or at least keep these characteristics intact in mapped types where the mapped type is generated from class types.
Use Cases
I've made a function called
multiple
that allows me to do multiple inheritance. In plain JavaScript, it works fine, like this:So far, after making type definitions for
multiple()
, the above works fine in TypeScript. playground example.However when making properties protected or private, those properties are lost from the mapped type returned from
multiple()
, and therefore inheritance of protected (or denial of accessing private) members doesn't work:Here's the playground example.
Because the
private
properties are deleted from the mapped type (just like theprotected
ones are), it becomes possible to inadvertently useprivate
properties because the type system says they don't exist:Here's the playground example.
Another problem is methods of the classes passed into
multiple()
are converted frominstance member function
toinstance member property
, and this happens:Here's the playground example.
Related
Checklist
My suggestion meets these guidelines:
The text was updated successfully, but these errors were encountered: