catamphetamine / libphonenumber-js

A simpler (and smaller) rewrite of Google Android's libphonenumber library in javascript
https://catamphetamine.gitlab.io/libphonenumber-js/
MIT License
2.77k stars 218 forks source link

Exposing `PhoneNumberType` similar to google-libphonenumber #392

Closed afiorito closed 3 years ago

afiorito commented 3 years ago

We use google's exported PhoneNumberType in a project I work on. We'd like to replace google's large library with yours but it does not expose this property.

google-libphonenumber has an exported enum:

export enum PhoneNumberType {
    FIXED_LINE = 0,
    MOBILE = 1,
    FIXED_LINE_OR_MOBILE = 2,
    TOLL_FREE = 3,
    PREMIUM_RATE = 4,
    SHARED_COST = 5,
    VOIP = 6,
    PERSONAL_NUMBER = 7,
    PAGER = 8,
    UAN = 9,
    VOICEMAIL = 10,
    UNKNOWN = -1
}

Steps to reproduce

  1. Try importing NumberType from libphonenumber-js.

Observed result

Import is not the same as google-libphonenumber since NumberType in libphonenumber-js is just the typescript type and not a concrete value.

Expected result

libphonenumber-js should expose the phone number types as an array, map, or enum etc...

I can try to create a PR if necessary. Thanks for looking into this.

catamphetamine commented 3 years ago

Hmm, I guess we could export that. Something like:

export enum PhoneNumberType {
    FIXED_LINE = 'FIXED_LINE',
    MOBILE = 'MOBILE',
    FIXED_LINE_OR_MOBILE = 'FIXED_LINE_OR_MOBILE',
    TOLL_FREE = 'TOLL_FREE',
    PREMIUM_RATE = 'PREMIUM_RATE',
    SHARED_COST = 'SHARED_COST',
    VOIP = 'VOIP',
    PERSONAL_NUMBER = 'PERSONAL_NUMBER',
    PAGER = 'PAGER',
    UAN = 'UAN',
    VOICEMAIL = 'VOICEMAIL',
    UNKNOWN = 'UNKNOWN'
}

Would that work?

afiorito commented 3 years ago

Yes that would work!

catamphetamine commented 3 years ago

@afiorito But there already is a type:

export type NumberType = undefined | 'PREMIUM_RATE' | 'TOLL_FREE' | 'SHARED_COST' | 'VOIP' | 'PERSONAL_NUMBER' | 'PAGER' | 'UAN' | 'VOICEMAIL' | 'FIXED_LINE_OR_MOBILE' | 'FIXED_LINE' | 'MOBILE';

Doesn't it work? If not, then why?

afiorito commented 3 years ago

We use the export from google-libphonenumber To loop through all the number types. This is not possible with the type definition exported from libphone number-js.

catamphetamine commented 3 years ago

@afiorito I haven't worked with TypeScript so it's not clear why the already existing export type NumberType won't work in your case.

afiorito commented 3 years ago

Well our code is not typescript so the type doesn't do anything in JavaScript code.

Using the google-libphonenumber, we would do:

for (const type in PhoneNumberType) {
    // handle phone number types
}

Trying to do the same thing in libphonenumber-js:

It's not possible to loop through, since types are not values.

for (const type in NumberType) { // NumberType “refers to a type, but is being used as a value.”

}
catamphetamine commented 3 years ago

Oh, so you're not talking about TypeScript then? You're talking about exporting something like this?

export const PhoneNumberType = {
    FIXED_LINE: 'FIXED_LINE',
    MOBILE: 'MOBILE',
    FIXED_LINE_OR_MOBILE: 'FIXED_LINE_OR_MOBILE',
    TOLL_FREE: 'TOLL_FREE',
    PREMIUM_RATE: 'PREMIUM_RATE',
    SHARED_COST: 'SHARED_COST',
    VOIP: 'VOIP',
    PERSONAL_NUMBER: 'PERSONAL_NUMBER',
    PAGER: 'PAGER',
    UAN: 'UAN',
    VOICEMAIL: 'VOICEMAIL'
}

There's no UNKNOWN in this library by the way.

catamphetamine commented 3 years ago

If yes, then why exactly do you iterate through the available types?

afiorito commented 3 years ago

If you could export an object like that it would be very appreciated!

We loop through the types to determine the input masking for phone number fields. We loop through all the types and generate example numbers. We use the example numbers to calculate the shortest and longest possible phone numbers for a country.

catamphetamine commented 3 years ago

We loop through all the types and generate example numbers.

This library currently doesn't provide any example numbers other than "mobile": https://github.com/catamphetamine/libphonenumber-js#getexamplenumbercountry-string-examples-object-phonenumber There're no other types of example numbers (and there're no plans for those currently, unless someone provides a really valid use case).

We use the example numbers to calculate the shortest and longest possible phone numbers for a country.

An example number doesn't cover all cases: there could be any number of digits in a number of a given type. An example number is just one random number. So your masks wouldn't work for all cases, therefore they wouldn't be valid. There's no single mask for a given phone number type.

I guess there's no need to export such an object then. Closing.

maurer2 commented 3 years ago

Hello, I believe this issue could be solved using const assertion in typescript 3.4+.

export const numberTypes = ['PREMIUM_RATE', 'TOLL_FREE', 'SHARED_COST', 'VOIP', 'PERSONAL_NUMBER', 'PAGER', 'UAN', 'VOICEMAIL', 'FIXED_LINE_OR_MOBILE', 'FIXED_LINE', 'MOBILE'] as const
export type NumberType = typeof numberTypes[number]

NumberType basically stays the same but is now derived from a readonly tuple. numberTypes can be exported and iterated over as proposed in https://github.com/catamphetamine/libphonenumber-js/issues/392#issuecomment-696700234.

Cheers