Skip to content

Re-type helper from @ember/component/helper#24986

Merged
mhegazy merged 2 commits intoDefinitelyTyped:masterfrom
tansongyang:ember-helper-fn
Apr 14, 2018
Merged

Re-type helper from @ember/component/helper#24986
mhegazy merged 2 commits intoDefinitelyTyped:masterfrom
tansongyang:ember-helper-fn

Conversation

@tansongyang
Copy link
Copy Markdown
Contributor

Previous typing caused an error about using private name Ember.Helper
when generating declaration files.

Fortunately, the previous typings were incorrect anyway, so we can
remove the reference to Ember.Helper and thus fix the issue.

Relevant links:

Please fill in this template.

  • Use a meaningful title for the pull request. Include the name of the package modified.
  • Test the change in your own code. (Compile and run.)
  • Add or edit tests to reflect the change. (Run with npm test.)
  • Follow the advice from the readme.
  • Avoid common mistakes.
  • Run npm run lint package-name (or tsc if no tslint.json is present).

Select one of these and delete the others:

If adding a new definition:

  • The package does not already provide its own types, or cannot have its .d.ts files generated via --declaration
  • If this is for an NPM package, match the name. If not, do not conflict with the name of an NPM package.
  • Create it with dts-gen --dt, not by basing it on an existing project.
  • tslint.json should be present, and tsconfig.json should have noImplicitAny, noImplicitThis, strictNullChecks, and strictFunctionTypes set to true.

If changing an existing definition:

If removing a declaration:

  • If a package was never on DefinitelyTyped, you don't need to do anything. (If you wrote a package and provided types, you don't need to register it with us.)
  • Delete the package's directory.
  • Add it to notNeededPackages.json.

Previous typing caused an error about using private name `Ember.Helper`
when generating declaration files.

Fortunately, the previous typings were incorrect anyway, so we can
remove the reference to `Ember.Helper` and thus fix the issue.

Relevant links:
* microsoft/TypeScript#5711
* microsoft/TypeScript#6307
* https://www.emberjs.com/api/ember/2.18/functions/@ember%2Fcomponent%2Fhelper/helper
* https://github.com/emberjs/ember.js/blob/v2.18.2/packages/ember-glimmer/lib/helper.ts#L120
@typescript-bot
Copy link
Copy Markdown
Contributor

typescript-bot commented Apr 14, 2018

@tansongyang Thank you for submitting this PR!

🔔 @jedmao @bttf @dwickern @chriskrycho @theroncross @mfeckie @alexlafroscia - please review this PR in the next few days. Be sure to explicitly select Approve or Request Changes in the GitHub UI so I know what's going on.

If no reviewer appears after a week, a DefinitelyTyped maintainer will review the PR instead.

Copy link
Copy Markdown
Contributor

@mfeckie mfeckie left a comment

Choose a reason for hiding this comment

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

Tiny nit, but otherwise looks good.

I wonder if there's a way to cover the case to provide prompts to folks that params[0] can be undefined.

Forcing undefined checking would help catch quite a few scenarios that have burned me in the past.

export const helper: typeof Ember.Helper.helper;
/**
* In many cases, the ceremony of a full `Helper` class is not required.
* The `helper` method create pure-function helpers without instances. For
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit creates

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for reviewing @mfeckie!

These comments were copied directly from the other location in the file, which I assume were copied from here. I'm leaning towards just letting it match the docs.

As for letting users know that params[0] can be undefined, that can hopefully be inferred from the fact that params is typed as any[], and any includes undefined. Again, I took this signature directly from the source. I know of no way to type index 0 differently from the other elements of the array. CC @chriskrycho in case he does.

@dwickern
Copy link
Copy Markdown
Contributor

I'm confused about what this solves. Would it be possible to add a test which previously fails to compile but now passes?

@typescript-bot
Copy link
Copy Markdown
Contributor

A definition author has approved this PR ⭐️. A maintainer will merge this PR shortly. If it shouldn't be merged yet, please leave a comment saying so and we'll wait. Thank you for your contribution to DefinitelyTyped!

@chriskrycho
Copy link
Copy Markdown
Contributor

This is solving for typed-ember/ember-cli-typescript#133.

I’m confused by how TS is erroring here, though. The name in question isn’t actually private.

@dfreeman I know you’d spiked out an alternative approach to solving this late yesterday as well?

@tansongyang
Copy link
Copy Markdown
Contributor Author

tansongyang commented Apr 14, 2018

@chriskrycho @dwickern The resources on this are limited; the two issues I linked were all I could find on this topic.

Essentially, this private name error gets thrown when you run tsc with --declaration. It's not clear to me exactly why it happens in this case. Unfortunately, those threads didn't really give me any information on how to fix it. And we need to use tsc with --declaration in ember-cli-typescript.

I tried a lot of different ways to keep the old type signature for helper, but once I realized that the old type signature wasn't technically correct, I decided it would save us all time to just re-type it.

@chriskrycho
Copy link
Copy Markdown
Contributor

Yeah, I’m familiar with the can’t-reference-private-types-in-public-exports rule—what’s perplexing is that the name being referenced isn’t private: it’s public API on a publicly exported type.

One thing we need to make sure of in any case is that the types for the Helper.helper (i.e. the static method on the class, IIUC) and this exported type match, since (again, IIUC; it’s been a bit since I looked at helper in detail) they should be the same.

@tansongyang
Copy link
Copy Markdown
Contributor Author

@chriskrycho Looks like the static helper is no longer present on the Helper class: source

@chriskrycho
Copy link
Copy Markdown
Contributor

Ah, solid. Type-def-wise, then: :shipit:

The best thing to add test-wise is basically just the previously-failing test from ember-cli-typescript itself, I think.

@dfreeman
Copy link
Copy Markdown
Contributor

dfreeman commented Apr 14, 2018

As far as I know Ember.Helper.helper still exists, so removing that could break existing globals usage, couldn't it?

The work I did yesterday was pointing me in the same direction as the change here, ultimately aiming for something like:

export function helper(/* ... */);
export default class Helper {
  // ...
  static helper: typeof helper;
}

So I'm 👍 on landing this (assuming we get Helper.helper sorted nevermind, I was mistaken) and I can incorporate it into the refactor I'm doing.

@tansongyang
Copy link
Copy Markdown
Contributor Author

To clarify for future readers: we have not removed Ember.Helper.helper. It's still there. This change only re-types the helper exported from @ember/component/helper.

@chriskrycho
Copy link
Copy Markdown
Contributor

Helpful clarification. Do the types match? That’s the only thing I’d like to be sure of as we go to merge!

@typescript-bot typescript-bot added the Other Approved This PR was reviewed and signed-off by a community member. label Apr 14, 2018
@mhegazy mhegazy merged commit ca3bf7f into DefinitelyTyped:master Apr 14, 2018
@tansongyang
Copy link
Copy Markdown
Contributor Author

tansongyang commented Apr 14, 2018

@chriskrycho They don't match exactly, but they're compatible. The new type is actually more permissive.

New signature:

helper(helperFn: (params: any[], hash?: any) => string): any;

Original Helper.helper signature:

helper(helper: (params: any[], hash?: object) => any): Helper;

The new type comes directly from the source. The source says that hash is actually any, not just object. Also, it returns a class SimpleHelper that I thought would be unnecessary clutter to add in this PR, so I just changed that to any.

@tansongyang tansongyang deleted the ember-helper-fn branch April 14, 2018 19:17
@Bouke
Copy link
Copy Markdown

Bouke commented Apr 16, 2018

First of all thank you for your work and time! However this change broke our build with the code below (the helper returned a number instead of a string). While the fix is an easy one, what is to be expected of the version numbering of these typings? Is backward compatibility something that is strived for, or not? In the later case, consumers would probably rather specify an explicit version instead of a caret version (^2.8.15).

import { helper } from '@ember/component/helper';

export function currentYear() {
    const now = new Date();
    return now.getFullYear();
}

export default helper(currentYear);
app/helpers/current-year.ts(8,23): error TS2345: Argument of type '() => number' is not assignable to parameter of type '(params: any[], hash?: any) => string'.
  Type 'number' is not assignable to type 'string'.

@tansongyang
Copy link
Copy Markdown
Contributor Author

@Bouke I apologize for that. I should have thought of that possibility.

As for versioning strategy, I know that we try to maintain backward compatibility as much as possible.

Pinging all the authors who were involved in the discussion: @chriskrycho @dwickern @mfeckie @dfreeman

Would it be best to just revert this PR? We originally did this to facilitate a PR in ember-cli-typescript. However, that PR ended up getting merged because we arrived at a different workaround. Now, I think it's just causing confusion.

@mfeckie
Copy link
Copy Markdown
Contributor

mfeckie commented Apr 16, 2018

My suggestion is to update to any and move forward.

At this stage I think it's a case of everyone doing their best as part of a community effort to provide and improve on the types.

I don't think it's realistic to think of the types in terms of 'breaking changes' as they are a community driven effort to document usages patterns. Each contributor draws from their experience and the ember source to provide best effort.

@Bouke This could be a good first PR for you to become a contributor :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Other Approved This PR was reviewed and signed-off by a community member.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants