#How do I type / overload a Stage1 Decorator?
20 messages · Page 1 of 1 (latest)
experimentalDecorators is "Stage2" ... which is really close to the Stage1 decorators.
A little confused by this - pretty sure the "experimental decorators" are a non-standard TS implementation that isn't 'stage anything'.
And the non-experimental decorators are stage 3
right, my actual project is not using Stage 3 decorators, nor Stage 2, but experimentalDecorators provides types for Stage 2 (the playground even says this)
but that's besides the point
I'm mostly just trying to make an overload work with an optional third argument:
function foo(...args: Parameters<typeof fooDecorator> | Parameters<typeof fooNonDecorator>) {
// decorators have 3 args, not 2 -- descriptor is always present
if (args.length === 3) {
return fooDecorator(...args) as void;
}
if (args.length === 2) {
if (typeof args[1] !== 'string' && typeof args[1] !== 'symbol') {
return fooNonDecorator(args[0], args[1]);
}
}
throw new Error('incorrect arity');
}
function fooNonDecorator<Value>(context: object, value: Value): Value {
console.log(context);
return value;
}
function fooDecorator(prototype: object, key: string | symbol, descriptor?: {}): void {
return descriptor as unknown as void; // no-op, TS types are wrong for Stage 1 Decorators
}
hmm, TS' PropertyDecorator type is wrong 
I was thinking I could override it:
declare global {
interface PropertyDecorator {
(target: any, key: string | symbol, descriptor: PropertyDescriptor): void;
}
}
but TS is saying "duplicate identifier"
which like.. fair
reason why I'm trying to override the type now is because I found out TS only considers a function a decorator based on the first two arguments, which is why I ha previousyl a ?: for descriptor
I have this so far -- in my first snippet, I forgot to actually overload the function
ooo, I may have done it
love that type guards let me lie to the type system. lol
ehh... maybe not. Just started trying to test with expect type
Ok, now this matches the situation I have locally
Preview:```ts
// declare global {
// interface PropertyDecorator {
// (target: any, key: string | symbol, descriptor: PropertyDescriptor): void;
// }
// }
function foo(prototype: object, key: string | symbol, descriptor?: PropertyDescriptor): void;
function foo<Value>(context: ThisType<object>, value: Value, _?: never): Reactive<Value>;
...```
It's just getting worse 😅
Preview:```ts
import type {Class, Constructor} from "type-fest"
function foo<Value, K>(
prototype: InstanceType<Class<K>>,
key: string | symbol,
descriptor?: PropertyDescriptor
): void
function foo<Value, K>(
context: ThisType<K>,
value: Value
): Reactive<Value>
type Foo<X> = X extends object ? never : X
...```
anyone have ideas?