-
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
Suggestion: optional interface #371
Comments
This is an alternative syntax suggestion for #340 But still 👍 |
Admittedly this way we do not break existing code. |
Another use case is making mixins easier |
Major question I have here is that an important use case for mix-ins is that you would be able to add one of these optional interfaces after the fact, which doesn't work well with having to declare this on the original class declaration. A solution for this JS pattern should be able to handle both cases. |
Sorry English is not my first language. I think we should expand use case.
|
+1 to something that can fix the current TypeScript mixins issues. Things like ReactJS using mixins widely and now it is very hard to make TypeScript compiler check all this things property without some effort. For example, there are more than 400 components in my project and it will be a little bit crazy to repeat React's method defs inside every component. On the other hand i want to type-check my code. So i find out to define classes like this: class LinkComponent extends ReactComponentBase<LinkComponentOptions,{}> implements React.ReactComponentSpec<LinkComponentOptions,{}> {
// extends Component<LinkComponentOptions,{}> for instance methods like setState
// implements React.ReactComponentSpec<LinkComponentOptions,{}> for type check livetime methods
}
// this is an `empty` class to satisfy the compiler
export class ReactComponentBase<P, S> implements React.ReactComponent<P, S> {
state: S;
props: P;
refs: { [ref: string]: React.ReactComponent<any, any>; };
getDOMNode: () => Element;
setProps: (nextProps: P, callback?: () => void) => void;
replaceProps: (nextProps: P, callback?: () => void) => void;
transferPropsTo: <C extends React.ReactComponent<P, any>>(target: C) => C;
setState: (nextState: S, callback?: () => void) => void;
replaceState: (nextState: S, callback?: () => void) => void;
forceUpdate: (callback?: () => void) => void;
} This leads to emty class export class MixinsComponent<P, S> extends ReactComponentBase<P, S> {
// example of mixin method
onValue: (bus: Bacon.Bus<any>, foo: (val: any) => void) => void;
} I think that implementation of normal mixins and unit types will make TypeScript much more friendly to such kind of libs. |
Dojo is another example of a big library which could benefit greatly from TypeScript but also makes extensive use of mixins. It is not uncommon for classes in an application to require the use of 3 extra mixins. Using Dojo with TypeScript isn't really practical at the moment. |
Just chiming in that this would be really useful. I had requested something like this on CodePlex last September. |
I love this suggestion because it is also useful for creating |
Is this need met by Intersection Types #3622 (committed)? See also Feature: type alternatives (to facilitate traits/mixins/type decorators) #727, aiming at the same target. Syntax: Synopsis:
Or you could provide a .d.ts which typed the function |
How about this use case? interface Foo {
foo: string;
}
interface Boo extends Foo? {
boo: string;
}
let x: Boo = getBoo();
if (x.foo) {
let y: Foo = x;
...
} Essence: I want to put make Here is an example that show current error when this is missing: interface Config<S> {
initialize<S>(...);
reduce<S>(state: S, action: any): S;
...
}
class Foo<S> {
configs: Config<S>[] = [];
reducers: Config<S>[] = []; // <-- Could have been Reducer<S>[];
addConfig(config: Config<S>) {
this.configs.push(config);
if (config.reduce) {
this.reducers.push(config);
}
}
do(state: S, action: any) {
return this.reducers.reduce((s, reducer) => {
// Object is possibly 'undefined' (with `strictNullCheck`)
return reducer.reduce(s, action);
}, state);
}
} Currently a workaround is to duplicate the signature of |
It's also useful for A very common pattern is to define default options object with values for all required properties It would be nice to internally use This would also be useful in redux when Object.assign is used as an immutable |
This kind of type operator would be extremely useful in many cases as discussed above. One that occurs to me and I don't think it's been mentioned, is simply sending and receiving isomorphic data from a JSON service. Generally when you do this you want anothing interface with optional properties to compose requests and the exact same interface except with required properties to type responses. function getUser(id: number): Promise<User>;
function updateUser(user: User?): Promise<void>; It would be especially powerful when mixed with subset types and intersection types. I don't think it should be limited to interfaces I think it should apply to type aliases. |
This is now class Bar {
// Bar does not have a foo property.
}
interface Bar extends Partial<IFoo> { }
new Bar().foo; |
I think this is useful syntax :)
sample.
How useful.
In real world.
case 1.
https://github.com/borisyankov/DefinitelyTyped/blob/705102df2b652bdbadad23561675116a26e48760/space-pen/space-pen.d.ts#L52
case 2.
// Emissary#emitter
https://github.com/atom/emissary#emitter
// .d.ts
https://github.com/borisyankov/DefinitelyTyped/blob/b4aba562ef4192bc3f2e770ab2018f89e047836b/emissary/emissary.d.ts#L13
// usage in TypeScript (dirty hack!)
https://github.com/vvakame/language-review/blob/d23f8797bbb6e99d636399a14c7035c4809ab365/lib/util/emissary-helper.ts#L11
The text was updated successfully, but these errors were encountered: