-
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
Decorator Type Mismatch? #9453
Comments
@rbuckton is this the expected behavior? |
I don't think the signature for The following does work: function CanRawr(target: new (...args: any[]) => Dinosaur) {
class Rawrable extends target {
static rawr () : void {
console.log(`RAWR`)
}
}
return Rawrable;
}
@CanRawr
export default class Dinosaur { } However, you probably want something like this: function CanRawr<TClass extends new (...args: any[]) => Object>(target: TClass) {
class Rawrable extends (<new (...args: any[]) => Object>target) {
static rawr() : void {
console.log(`RAWR`)
}
}
return <TClass>Rawrable;
} Unfortunately, the cast of |
@rbuckton So, in other words, the current decorator spec expects you to know ahead of time what base type you are trying to The use-case we were already using decorators for is applying // MonkeyPatch just calls Object.defineProperty with the correct arguments
@MonkeyPatch(Symbol.hasInstance, {
value: (lhs) => ((typeof lhs) === 'string')
})
class MyString { /* */ }
// in some other code, where the environment supports Symbol.hasInstance...
"hello" instanceof MyString // => true This works fine. Then the use-case we want to support looks more like: @Model
class User {
@Validator({ // suppose this metadata is used by the @Model decorator to create the `validate()` method
test (lhs) { return lhs < 10 }
})
uid: number
}
// Now, in some other code...
// Because TypeScript uses Structural Typing...
const exampleUser : User = {
uid: 5
} // type-checks.
// And, while it doesn't type-check, at runtime you can have...
User.validate(exampleUser) // => true
User.validate({ uid: 10 }) // => false This can actually be done right now using type metadata provided from the compiler with the right I guess the question is, then: if the codegen can, and already does, support creating mixins like this, then maybe we could look into making it type-check? I, for one, would love to see a type-using decorator-based modeling library that enforces your types both before and after compilation/codegen. While I can accomplish the latter, the former currently requires a workaround something like: @Model
class MyModel extends SomeBaseModelIWillOverwriteMethodsOnUsingADecorator {
/* ... */
} Which will type-check so long as that dummy base model includes a stub for I'll be the first to admit that this experiment, while it works, does not seem like it has an obvious type-checking solution. In playing around, I've even tried out using intersection types and an interface like: @Model
class IUser {
uid: number
}
export const User = IUser as any as IModel & User Where IModel is an interface containing Sorry for the length of the comment, but hopefully it was insightful/constructive. I get the impression that I'm using this feature in a way other than it was intended! |
Are there any plans to let class decorators add new members to the type in the type checker? With TS 2.2 out, it seems very odd that this doesn't work: function CanRawr(target: new (...args: any[]) => object) {
class Rawrable extends target {
rawr () : void {
console.log(`RAWR`)
}
}
return Rawrable;
}
@CanRawr
class Dinosaur { }
let d = new Dinosaur();
d.rawr(); // Not OK But this does: // ... same CanRawr function
class Dinosaur {}
class TRex extends CanRawr(Dinosaur) {}
let t = new TRex();
t.rawr(); // OK |
this is tracked by #4881 |
Support for mixin classes should be available now, see: http://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-2.html#support-for-min-in-classes |
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed. |
@rbuckton I think there may still be an issue here, this code compiles in 2.4.0 but does not in 2.4.1-insiders:
Gives the error:
Where ComponentClass is as defined in react.d.ts:
|
I'm confused.. this issue was closed, but @mhegazy linked to supporting mixins, not decorators. Is this still not supported? |
No, currently a decorator does not affect types in the class. The Decorators proposal for adoption to ECMAScript differs from the TypeScript implementation and we are unlikely to make substantive changes to our Decorators support until the official proposal reaches Stage 3. In the meantime, we do offer support for mixins which gives you the ability to augment a type (per @mhegazy's comment above). |
TypeScript Version: nightly (2.0.0-dev.20160630)
Code (This is a fairly contrived example.)
Expected behavior:
Everything typechecks.
Actual behavior:
Code compiles, but logs a hard to understand error. Compiled code works as expected.
This is strange - looking at the signature for
ClassDecorator
:I would think that I am allowed to return a Function in place of a TFunction.
Perhaps I am doing something wrong? But the code compiles and runs, and does what I expect.
The text was updated successfully, but these errors were encountered: