Imported libraries dropped when spread used on foo: any (new in 2.3)
Closed this issue · 6 comments
This is a new bug in 2.3. When you use a spread in JSX and the type of the variable being spread is "any" some referenced libraries are not kept.
There is also a full (but minimal) example in this repo: https://github.com/luggage66/ts23issue (just npm install && tsc && cat lib/foo.js
)
TypeScript Version: 2.3.2
Code
import * as React from 'react';
import * as cx from 'classnames';
export default class FooComponent extends React.Component<any, void> {
render() {
let buttonProps; // any
buttonProps = {
onClick: () => undefined
};
return <button {...buttonProps}>
<span className={cx('class1', { class2: true })} />
</button>;
}
}
Expected behavior:
The output to include require('classnames')
(or the equivalent in your configured module system).
Actual behavior:
require('classnames')
is missing when {...foo} is used when type of foo is "any".
Using --noImplicitAny
will also cause require('classnames')
to be in the output.
I am also having dropped imports due to using the spread operator.
However, I have two differences from the reported issue:
noImplicitAny
doesn't seem to have an effect -- the imports are trimmed either way, for me.- The object I am spreading is of type
{[attributeName: string]: ''}
, notany
The outcome is the same, though. With the spread, imports are trimmed for anything that is referenced only in the children of the jsx element. If I remove the spread, everything is okey-dokey; and if I roll back typescript to an earlier version, it's hunky-dory then, too.
Using es6-style modules fixes the problem, but only because it turns off import-trimming entirely :/.
casting to {}
fixes it. it's a temporary fix until this is resolved.
@diiq want to make sure I understand your scenario and that the PR address your issue
(Note i use above code with modify spread object type)
import * as React from 'react';
import * as cx from 'classnames';
export default class FooComponent extends React.Component<any, void> {
render() {
let buttonProps : {[attributeName: string]: ''}
buttonProps = {
onClick: () => undefined
};
return <button {...buttonProps}>
<span className={cx('class1', { class2: true })} />
</button>;
}
}
import * as React from 'react';
export default class FooComponent extends React.Component {
render() {
// with this line, it'll include the 'classnames' lib
// let buttonProps: object;
// with this line, it will not
let buttonProps; // any
buttonProps = {
onClick: () => undefined
};
//let i = <span className={cx('class1', { class2: true })} />;
return React.createElement("button", Object.assign({}, buttonProps),
React.createElement("span", { className: cx('class1', { class2: true }) }));
}
}
@yuti that looks right. This is used all over my codebase, so I rolled back to < 2.3 -- which means I haven't verified that what you posted makes the problem occur, but it does look like my situation.
I'm using React and Glamor; it's spreading Glamor's StyleAttribute type that causes the problem, if that helps.
Let me know if you need more info from me.
@diiq thanks for the information. The PR should address your issue as well. @luggage66 @alitaheri @diiq Give tomorrow nightly built a try and let us know