sindresorhus / type-fest

A collection of essential TypeScript types
Creative Commons Zero v1.0 Universal
14.26k stars 541 forks source link

Improve `Opaque` type to encapsulate unique symbol tag #298

Open younho9 opened 3 years ago

younho9 commented 3 years ago

Because opaque.d.ts is not module file, unique symbol tag of the Opaque type is exposed

스크린샷 2021-10-20 오후 3 49 49

Also, the typescript compiler does not regard following as an error.

import {Opaque} from 'type-fest'
import {tag} from 'type-fest/source/opaque';

type AccountNumber = Opaque<number, 'AccountNumber'>;

declare const accountNumber: AccountNumber

accountNumber[tag]

I suggest adding export {} in opaque.d.ts. (This is added if use typescript compiler.)

// ...

export type Opaque<Type, Token = unknown> = Type & Tagged<Token>;

export {}

Then, the typescript compiler complains that the tag is not exported.

import {Opaque} from 'type-fest'
import {tag} from 'type-fest/source/opaque'; // Error: Module '"type-fest/source/opaque"' declares 'tag' locally, but it is not exported.ts(2459)

type AccountNumber = Opaque<number, 'AccountNumber'>;

declare const accountNumber: AccountNumber

accountNumber[tag] // Error: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'Number & Tagged<"z">'.ts(7053)

Upvote & Fund

Fund with Polar

sindresorhus commented 3 years ago

I plan to make this package ESM when we can target TS 4.5. I guess we could do this in the meantime.

Are you sure adding export {} doesn't have any negative side-effects?

younho9 commented 3 years ago

TypeScript Playground of CJS Output ({ "module": "commonjs", "target": "ES2019" })

TypeScript Playground of ESM Output ({ "module": "ES2020", "target": "ES2020" })

Well, I'm not completely sure, but there seems to be no difference in the .d.ts file between cjs and esm within the scope of the current target. If look at the .d.ts output, you can see that export {} is added to hide internal variables, whether esm or cjs.

It would be better to consider support when making this package a pure ESM package.