TS version: 2.9+ (Relevant issues: https://github.com/Microsoft/TypeScript/issues/14377#issuecomment-379935736, https://github.com/Microsoft/TypeScript/issues/14844, )
test.d.ts
export interface TestProperties {
bar: string;
baz: number;
}
export class Test {
foo(param: TestProperties);
}
test.js
/**
* @type { import("./test").Test }
*/
export class Test {
foo({ bar, baz }) {
bar = 7;
}
}
Expected behavior: Throw an error when trying to assign 7 to bar
Actual behavior: no error
If I make this change, it works:
test.js
/**
* @type { import("./test").Test }
*/
export class Test {
/**
* @param { import("./test").TestProperties } param
*/
foo({ bar, baz }) {
bar = 7;
}
}
Correct behavior: Type '7' is not assignable to type 'string'.
Giving Test the correct type definition should also give foo the correct definition. Ideally, we wouldn't even need to do either and we should be able to just do:
/** @typedef { import("./test") } Test */
Or just be able to have TS pick up on the fact that we defined a .d.ts file for our .js file
@bennypowers
A fundamental issue here is that in TypeScript a declaration is never contextually typed. A declaration defines the shape/type of a name, and does not get/inherit that from somewhere else..
for instance class C implements I {} does not make C get any properties from I that it did not define. it just asserts that instance of C are assignable to I.
Similarly here, class Test declares what that class does, would be very strange if the shape of Test changes just because of a change in a .d.ts file, that may or may not be related.
So I do not think this is a feature we should be supporting for JSDoc.
That said, i think there is a need to be able to declare properties on classes.. I have made a similar suggestion in https://github.com/Microsoft/TypeScript/issues/22896#issuecomment-376592535.
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.
Most helpful comment
@bennypowers