Skip to content
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

feat(typescript): update to typescript 4.3.5 #3103

Merged
merged 11 commits into from
Oct 19, 2021
Merged

Conversation

ltm
Copy link
Contributor

@ltm ltm commented Oct 14, 2021

Pull request checklist

Please check if your PR fulfills the following requirements:

  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)
  • Build (npm run build) was run locally and any changes were pushed
  • Unit tests (npm test) were run locally and passed
  • E2E Tests (npm run test.karma.prod) were run locally and passed
  • Prettier (npm run prettier) was run locally and passed

Pull request type

Please check the type of change your PR introduces:

  • Bugfix
  • Feature
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • Documentation content changes
  • Other (please describe):

What is the current behavior?

Stencil is compiled using TypeScript 4.2.3.

What is the new behavior?

Stencil is compiled using TypeScript 4.3.5.

Does this introduce a breaking change?

  • Yes
  • No

Testing

npm run build, npm test, npm run test.karma.prod

Other information

@ltm ltm requested a review from a team October 14, 2021 13:15
Copy link
Member

@rwaskiewicz rwaskiewicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took this for a spin in a new Stencil component library (spun up with npm init stencil) and in Ionic Framework core. LGTM, just a few questions/small asks

* @param tags An array of JSDocTagInfo objects.
* @return An array of CompilerJsDocTagInfo objects.
*/
export const mapJSDocTagInfo = (tags: ts.JSDocTagInfo[]): d.CompilerJsDocTagInfo[] => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we mark the tags parameter as readonly?

Suggested change
export const mapJSDocTagInfo = (tags: ts.JSDocTagInfo[]): d.CompilerJsDocTagInfo[] => {
export const mapJSDocTagInfo = (tags: ReadonlyArray<ts.JSDocTagInfo>): d.CompilerJsDocTagInfo[] => {

(I don't think we can do the same with the return type, because that would lead to changes in other functions, like transform-utils.ts#mapJSDocTagInfo)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL - opted for the equivalent readonly ts.JSDocTagInfo[].

* @return An array of CompilerJsDocTagInfo objects.
*/
export const mapJSDocTagInfo = (tags: ts.JSDocTagInfo[]): d.CompilerJsDocTagInfo[] => {
return tags.map((tag) => ({ ...tag, text: tag.text?.map((part) => part.text).join('') }));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we have >1 SymbolDisplayPart in a JSDocTagInfo, we're joining them in this change with .join('') - can we add a comment as to why we need to join them? From my own playing around it seems to be related to how the pieces of the JSDoc are structured internally. For example I add some 'doc' to a boilerplate Stencil component library:

  /**
   * The middle name
   * @argument i love to argue
   * @async nsync backstreet boys
   */
  @Prop() middle: string;

Which internally becomes:

{ text: 'i', kind: 'parameterName' }
{ text: ' ', kind: 'space' }
{ text: 'love to argue', kind: 'text' }
{ text: 'nsync backstreet boys', kind: 'text' }

When we create a JSON readme, this all looks right to me:

{
          "name": "middle",
          "type": "string",
          "mutable": false,
          "attr": "middle",
          "reflectToAttr": false,
          "docs": "The middle name",
          "docsTags": [
            {
              "name": "argument",
              "text": "i love to argue"
            },
            {
              "name": "async",
              "text": "nsync backstreet boys"
            }
          ],
          "values": [
            {
              "type": "string"
            }
          ],
          "optional": false,
          "required": false
        }
      ],

Is my understanding right there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. I've added a comment describing this.

export function mockStencilSystem(): TestingSystem {
return createTestingSystem();
const sys = createTestingSystem();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have four callsites for createTestingSystem in Stencil. Does it make sense to move the type guard and the associated usage to the end of createTestingSystem() to get better type safety through the codebase?

+ function isTestingSystem(sys: CompilerSystem): sys is TestingSystem {
+  return 'diskReads' in sys && 'diskWrites' in sys;
+ }
+ 
- export const createTestingSystem = () => {
+ export const createTestingSystem = (): TestingSystem => {
   ...
- return Object.defineProperties(sys, {
+  const testingSystem = Object.defineProperties(sys, {
     diskReads: {
       get() {
          return diskReads;
      },
      set(val: number) {
        diskReads = val;
      },
    },
    diskWrites: {
      get() {
        return diskWrites;
      },
      set(val: number) {
        diskWrites = val;
      },
    },
  });

+  if (!isTestingSystem(testingSystem)) {
+    throw new Error('could not generate TestingSystem');
+  }
+  return testingSystem;

This would allow us to refrain from 'knowing we need to put a typeguard here' everytime we call this testing function, and helps us make the guarantee in the function signature of createTestingSystem that this is going to return a TestingSystem

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. It's a little unclear why we have both mockStencilSystem() and createTestingSystem(). I took the liberty to move the TestingSystem interface to testing-sys.ts as well. FWIW, the only place we actually use the diskReads and diskWrites properties is in in-memory-fs.spec.ts

describe('transform utils', () => {
it('flattens TypeScript JSDocTagInfo to Stencil JSDocTagInfo', () => {
const tags = [
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can we add a test for no/empty text?

Suggested change
{
{
name: 'param',
text: [],
},
{

];

expect(mapJSDocTagInfo(tags)).toEqual([
{ name: 'param', text: 'foo the first parameter' },
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To coincide with my suggestion above:

Suggested change
{ name: 'param', text: 'foo the first parameter' },
{ name: 'param', text: '' },
{ name: 'param', text: 'foo the first parameter' },

@ltm ltm requested a review from rwaskiewicz October 18, 2021 14:40
Copy link
Member

@rwaskiewicz rwaskiewicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Going to hold off on merging, as I think @splitinfinities wanted to give this a look over as well (if that's not the case I'll merge it once he says either way)

@splitinfinities
Copy link
Contributor

This upgrade worked great on the Apps & Component Libraries that I compiled. Great job!

@rwaskiewicz rwaskiewicz merged commit e1d4e66 into main Oct 19, 2021
@rwaskiewicz rwaskiewicz deleted the rwaskewicz/ts4.3 branch October 19, 2021 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants