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

Refactor: Convert source files to TypeScript #29

Merged
merged 7 commits into from
Jul 28, 2020

Conversation

HipsterBrown
Copy link
Contributor

/domain @Betterment/js-platform @Betterment/test_track_core
/no-platform

To support how we write front end code at Betterment, this PR converts the source JS files into TypeScript and emits type definitions to ship with the package.

@nanda-prbot
Copy link

Needs somebody from @Betterment/js-platform and @Betterment/test_track_core to claim domain review

Use the shovel operator to claim, e.g.:

@myname << domain && platform

HOW TO: Claim a Review

package.json Outdated
@@ -6,7 +6,7 @@
"main": "dist/testTrack.bundle.js",
"module": "dist/testTrack.js",
"scripts": {
"build": "rollup -c",
"build": "tsc && rollup -c",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

rollup won't fail the build if TypeScript fails to compile, so running the compiler before will gives us warnings in CI about broken types.

@@ -42,7 +55,7 @@ class ABConfiguration {

if (splitVariants) {
const trueVariant = this._getTrueVariant();
const trueVariantIndex = splitVariants.indexOf(trueVariant);
const trueVariantIndex = splitVariants.indexOf(trueVariant.toString());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

splitVariants is an array of strings, so we need to ensure trueVariant is a string.

@aburgel
Copy link
Collaborator

aburgel commented Jul 24, 2020

<< domain

@nanda-prbot
Copy link

Needs @aburgel to provide domain review

When you finish a round of review, be sure to say you've finished or sign off on the PR, e.g.:

TAFN or DomainLGTM

If you're too busy to review, unclaim the PR, e.g.:

@myname >> domain

HOW TO: Give Feedback

package.json Outdated Show resolved Hide resolved
private _visitor: Visitor;
private _splitRegistry: SplitRegistry;

constructor(options: ABConfigurationOptions) {
if (!options.splitName) {
throw new Error('must provide splitName');
Copy link
Collaborator

Choose a reason for hiding this comment

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

pardon the typescript ignorance... but does typechecking allow us to remove runtime checks like this? i guess i'm asking whether the ts compiler will add runtime checks for when you are calling this from regular old javascript.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i'm asking whether the ts compiler will add runtime checks for when you are calling this from regular old javascript

The compiler won't do that for us. There are some libraries like io-ts that allow for us to model types and validate them at runtime.

export type AssignmentOptions = {
splitName: string;
variant: string | null;
context?: string;
Copy link
Collaborator

Choose a reason for hiding this comment

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

i think context is required.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We use this class in TestTrackConfig and context is not passed in there.

src/identifier.ts Outdated Show resolved Hide resolved
src/mixpanelAnalytics.ts Outdated Show resolved Hide resolved
src/varyDSL.ts Outdated Show resolved Hide resolved

let loaded = null;
let loaded: null | ((value?: Visitor | PromiseLike<Visitor>) => void) = null;
Copy link
Collaborator

Choose a reason for hiding this comment

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

for my understanding, is this to support how promises work? you can either pass in the actual resolved object or another promise?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, the type signature for resolve in the Promise constructor is:

declare type PromiseConstructorLike = new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) => PromiseLike<T>;

Where T stands for our Visitor interface.

src/identifier.ts Outdated Show resolved Hide resolved
for (let splitName in this.getSplits()) {
const split = this._splits[splitName];
const split = this.getSplits()[splitName];
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍 good catch, this may have led to bugs with the chrome extension.

src/session.ts Outdated Show resolved Hide resolved
@aburgel
Copy link
Collaborator

aburgel commented Jul 24, 2020

tafn! but i'd love some other typescript eyes on this. @joejansen?

@nanda-prbot
Copy link

@HipsterBrown needs to incorporate feedback from @aburgel. Bump when done.

HOW TO: Resolve Feedback

@HipsterBrown
Copy link
Contributor Author

Bump

I updated the rollup build to use the official plugins for typescript, node-resolve, and commonjs. The official babel plugin requires using Node v10+, so I didn't introduce that update here.

I also created and exported an AnalyticsProvider interface for the MixpanelAnalytics class to conform and give feedback to users that want to introduce their own analytics client.

@nanda-prbot
Copy link

Needs @aburgel to provide domain review

When you finish a round of review, be sure to say you've finished or sign off on the PR, e.g.:

TAFN or DomainLGTM

If you're too busy to review, unclaim the PR, e.g.:

@myname >> domain

HOW TO: Give Feedback

import { terser } from 'rollup-plugin-terser';
import typescript from '@rollup/plugin-typescript';

const customTSConfig = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

looks like this is coming from tsconfig.json. should we just load that file so we don't have to keep them in sync?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea, that's a good idea. I want to keep most of the settings from the tsconfig.json but need to override the emitDeclarations setting for the UMD build due to constraints from the the @rollup/plugin-typescript


class ConfigParser {
getConfig(): Config {
if (typeof window.atob === 'function') {
Copy link
Collaborator

Choose a reason for hiding this comment

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

i think base64 delegates to window.atob if it's available, so we may be able to remove this conditional. (we can do this another time, just pondering out loud)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yea I'm going to do some refactoring here when I replace base-64 with abab https://app.asana.com/0/786534243298162/1147959806039095

src/mixpanelAnalytics.ts Outdated Show resolved Hide resolved
@aburgel
Copy link
Collaborator

aburgel commented Jul 27, 2020

domainlgtm! nice work!

@nanda-prbot
Copy link

Approved! 🚢 🤘 🌟

@HipsterBrown HipsterBrown merged commit ddbdff8 into Betterment:master Jul 28, 2020
@HipsterBrown HipsterBrown deleted the nhehr/typescript branch July 28, 2020 13:15
@joejansen
Copy link
Contributor

lgtm! great job!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants