Skip to content

Conversation

@mjackson
Copy link
Member

@mjackson mjackson commented Feb 6, 2020

DO NOT MERGE

This is a first pass at attempting to convert this codebase to TypeScript. There are still a few TS errors:

  • packages/history/{browser,hash,memory}.ts complain about using the file extension in import './index.ts', but I can't figure out how to get the build (Rollup) to work w/out the extension
  • packages/history/index.ts has an error about __DEV__ not being defined, but when I added a global declare, the __DEV__ blocks appeared in the production build
@maraisr
Copy link

maraisr commented Feb 6, 2020

Point 1: in your rollup.config.js file, under the nodeResolve plugin for umd's, simply define the extensions property: ie

nodeResolve({extensions: ['.ts']})

re the esm's, yeah will need to do some investigation. The tsPlugin resolves this for me, but you cant stack babelPlugin on top of typescriptPlugin with Rollup. So ill get back to you.

Point 2: not sure how you declared that global. But make sure it's a .d.ts file, as they don't get emited.

So; create a global.d.ts file, and in there declare const __DEV__: boolean. Then inside your tsconfig.json file, in the include block, prepend the global.d.ts file to the list. Depeneding on where you put that file, you could omit the .ts suffix from your existing include block, as its not needed. Unless you have allowJs: true only typescript files will ever match the glob.

hash?: string;
};

export type State = object;
Copy link
Contributor

@OliverJAsh OliverJAsh Feb 7, 2020

Choose a reason for hiding this comment

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

Would unknown be a better default? object excludes primitives such as numbers, but there's no reason to restrict state to non-primitives?

This is what I used for the default on DefinitelyTyped.

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually:

The state object can be anything that can be serialized.

https://developer.mozilla.org/en-US/docs/Web/API/History/pushState#Parameters

So we should exclude functions amongst other things.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for commenting here. I've updated this type to be object | null, but I'm not sure that's exactly what we want. Ideally I'd like this type to not be too restrictive. I just want to require some kind of an object, not a primitive, so object seemed like a good fit. Yes, there will be problems if it is not serializable, but I'm not aware of a nice, simple way to specify that in TS.

const PopStateEventType = 'popstate';

const readOnly = __DEV__ ? obj => Object.freeze(obj) : obj => obj;
const readOnly = __DEV__ ? (obj: any) => Object.freeze(obj) : (obj: any) => obj;
Copy link
Contributor

Choose a reason for hiding this comment

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

Perhaps this should be generic:

const readOnly = __DEV__ ? <T>(obj: T) => Object.freeze(obj) : <T>(obj: T) => obj;

or

const readOnly = <T>(obj: T) => __DEV__ ? Object.freeze(obj) : obj;

any completely disables type checking so it should be avoided, e.g.

declare const myObject: any; myObject.foo.bar.baz // no compile time error, but runtime exception!!

For this reason, unknown or generics should be used instead (depending on the use case)

Copy link

Choose a reason for hiding this comment

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

I like the first one! 🕺

Choose a reason for hiding this comment

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

const readOnly: typeof Object.freeze = __DEV__ ? Object.freeze : ((obj:any) => obj);

I think this one is better. This means:

const readOnly: { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
Copy link
Member Author

Choose a reason for hiding this comment

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

This is a great suggestion, thank you @OliverJAsh. I'll fix it.

@TrySound
Copy link
Contributor

TrySound commented Feb 7, 2020

Do not forget .js. The package has dependencies.

nodeResolve({extensions: ['.ts', '.js']}) 
@mjackson mjackson force-pushed the dev branch 4 times, most recently from d9b4806 to 21e6b8c Compare March 25, 2020 23:34
@mjackson mjackson closed this Apr 17, 2020
@mjackson mjackson deleted the ts branch April 17, 2020 01:10
@OliverJAsh OliverJAsh mentioned this pull request Apr 17, 2020
Merged
@mjackson
Copy link
Member Author

The package has dependencies

Not anymore, @TrySound! 😅

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

Labels

None yet

7 participants