| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
|
||
| // A valid base type is any non-generic object type or intersection of non-generic | ||
| // object types. | ||
| function isValidBaseType(type: Type): boolean { |
There was a problem hiding this comment.
Return type could be : type is BaseType ?
Sorry, something went wrong.
There was a problem hiding this comment.
Well, BaseType is the most restrictive type we can express for a valid base type, but there are still BaseType instances that aren't valid base types (e.g. intersections containing type parameters). So, wouldn't be correct in the negative sense.
Sorry, something went wrong.
|
In the second block of examples, are N1 and N2 missing x: string in the commented result? |
Sorry, something went wrong.
There was a problem hiding this comment.
Please add some tests for the changes in the apparent type for this in intersection types.
Sorry, something went wrong.
|
Anders Hejlsberg (@ahejlsberg) I'm not 100% sure but it seems like this change breaks a common pattern I use (and probably others, at least in the future) with React. This worked in yesterday's nightly build: export class MyComponent extends React.Component<{ someValue: number }, {}> {
shouldComponentUpdate(nextProps: this["props"], nextState: this["state"]) {
if (nextProps.someValue > 0) {
// ...
}
}
}But now errors: // Error: Property 'someValue' does not exist on type 'this["props"]'.' The problem might be related to the fact that this["props"] has the type: {
children?: React.ReactNode;
} & {
someValue: number;
}I've tried to work around this by using typeof this.props instead but that didn't seem to help: export class MyComponent extends React.Component<{ someValue: number }, {}> {
shouldComponentUpdate(nextProps: typeof this.props, nextState: typeof this.state) {
if (nextProps.someValue > 0) {
// ...
}
}
}
// Error on 'typeof this.props': Identifier expectedThe relevant ambient declaration for React.Component looks like: // Base component for plain JS classes
class Component<P, S> implements ComponentLifecycle<P, S> {
constructor(props?: P, context?: any);
constructor(...args: any[]);
// ...
props: { children?: ReactNode } & P;
state: S;
// ...
} |
Sorry, something went wrong.
|
Rotem Dan (@rotemdan) Yes, there was a minor typo that's causing this issue. I will have a fix shortly. |
Sorry, something went wrong.
|
Thanks, I temporarily worked around these errors by creating a type alias for this[props], which was relatively easy. I'm intentionally using the latest nightly builds with a large code base to try to help to quickly identify issues of this kind. If I update every day it makes it easy to speculate what could have been the cause by looking at the commits of the previous day. |
Sorry, something went wrong.
|
Anders Hejlsberg (@ahejlsberg) this is just CRAZY! I can now build a decorator, export it as const and export a type with the same name. export class Class implements MyDecorator<'myMethod'> {
@MyDecorator()
myMethod() { // myMethod's signature is fixed, if changed -> type error! if name changes -> type error
}
}This is getting to be the best type system ever, I am really amazed! thank you guys! |
Sorry, something went wrong.
|
It would be very nice if a class decorator could "replace" the original class type with respect to the type system so that we could use such a decorator to fully implement a mixin, both the implementation at runtime and the extended type for compile time. |
Sorry, something went wrong.
|
Forgive me if it's a silly question, but would this change help at all with what I'm looking for here? |
Sorry, something went wrong.
|
Brand new to TS here. Is there a simple way to make this work? function Foo() {}
class Bar extends Foo {
constructor() {
super()
console.log('Bar!')
}
}
new Bar |
Sorry, something went wrong.
|
A class needs to inherit from something that has a "construct signature"; i.e. a declaration of what the shape of the object it returns if called with new. a function does not have that. if this is your function, i would suggest switching it to a class, and switching this.prop assignments in it to property declarations. if this is a function you got from a different module, then consider declaring it as a calss, e.g. declare class Foo {}. you can always cast the type to a constructable type, e.g. const Foo: { new (): FooInstance } = <any>function Foo() { } |
Sorry, something went wrong.
In reality it is a dynamically generated class as in the following (working) cases: class Foo extends multiple(One, Two, Three) {}class Foo extends MixinOne(MixinTwo(Three)) {}I am relying on those features to do interesting things. These type of things are possible in JS. Can I use interfaces somehow? |
Sorry, something went wrong.
|
Oh, another thing. I know how to declare a type, for example, so that I can extend from a Backbone.View, by declaring the class definition. But how do I declare that some function returns a specific class? F.e., // Third party
function get(){
return Backbone.View
}
// My file
Class Foo extends get() {} |
Sorry, something went wrong.
|
Joe Pea (@trusktr) you need #4890, this should land in the next few days. |
Sorry, something went wrong.
|
Mohamed Hegazy (@mhegazy) Once released, how would I write that last example? Is the following correct? interface Constructable<T> {
new (...args): T;
}
// Third party
function get(): Constructable<Backbone.View> {
return Backbone.View
}
// My file
Class Foo extends get() {}What about the following? function multiple(...classes: whatGoesHere?): Constructable<whatGoesHere?> {
// uses Proxy
}
class Foo extends multiple(One, Two, Three) {} |
Sorry, something went wrong.
|
Does this also allow extending from typeof expressions? |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
With this PR we permit classes and interfaces to derive from object types and intersections of object types. Furthermore, in intersections of object types we now instantiate the this type using the intersection itself. Collectively these changes enable several interesting "mixin" patterns.
In the following, a type is said to be object-like if it is a named type that denotes an object type or an intersection of object types. Object-like types include named object literal types, function types, constructor types, array types, tuple types, mapped types, and intersections of any of those.
Interfaces and classes may now extend and implement types as follows:
Some examples:
An interface or class cannot extend a naked type parameter because it is not possible to consistently verify there are no member name conflicts in instantiations of the type. However, an interface or class can now extend an instantiation of a generic type alias, and such a type alias can intersect naked type parameters. For example:
The this type of an intersection is now the intersection itself:
All of the above can be combined in lightweight mixin patterns like the following:
Also, mixin classes can be modeled, provided the base classes have constructors with a uniform shape:
We're still contemplating type system extensions that would allow the last example to be written without type assertions and in a manner that would work for arbitrary constructor types. For example, see #4890.
EDIT: Mixin classes are now implemented by #13743.
Fixes #10591.
Fixes #12986.