Skip to content

Experimental (deprecated) decorators are included by default #63346

@OldStarchy

Description

@OldStarchy

⚙ Compilation target

esnext

⚙ Library

ESNext

Missing / Incorrect Definition

The old experimental decorators have (to my knowledge) always been opt-in, which means the types for those decorators are wrong by default. Now we have new decorators which are available by default, but still the old decorator types exist.

My project is using esnext lib, but it doesn't matter which version you use because they all end up including the legacy types.

The import chain is esnext -> es2024 -> es2023 -> es2022 -> es2021 -> es2020 -> es2019 -> es2018 -> es2017 -> es2016 -> es2015 -> es6 -> es5 -> decorators.legacy

In order to make my life "easier" I have defined a handful of types describing the actual function signatures of the new decorators, but my ClassDecorator (in my own types.d.ts) and the legacy decorator types are conflicting.

(See also: #16132 (comment))

Sample Code

yarn init
yarn add typescript
yarn tsx --init
touch types.d.ts
touch main.ts

types.d.ts

type ClassDecorator<
	This,
	Class extends abstract new (...args: any[]) => This,
> = (Class: Class, context: ClassDecoratorContext<Class>) => void | Class;

main.ts

// adding this import fixes the type error, but the import line itself becomes an error
// > File '[snip]/types.d.ts' is not a module.
// import type {ClassDecorator} from './types';

const foo = Symbol('foo');
const bar = Symbol('bar');
type FoobarMixin = {
	[foo]: number;
	[bar](): string;
};

function foobarMixin<
	This extends FoobarMixin,
	Class extends abstract new (...args: any) => This = abstract new (
		...args: any
	) => This,
>(): ClassDecorator<This, Class> {
	return (target: Class, _context: ClassDecoratorContext<Class>) => {
		target.prototype[foo] = 42;
		target.prototype[bar] = function () {
			return 'hello';
		};
	};
}

interface Thing extends FoobarMixin {}
@foobarMixin()
class Thing {}

console.log(new Thing()[foo]);
console.log(new Thing()[bar]());

Documentation Link

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions