Closed dsbudiac closed 1 year ago
Is it not?
https://github.com/catamphetamine/libphonenumber-js/blob/master/index.d.ts
you're linking the type definition.
you're linking the type definition.
Yes
You can't use instanceof PhoneNumber
for a type definition. You need the actual class for runtime.
Ah, I see.
But, you could change the code so that it works without instanceof PhoneNumber
:
function parse(input: string | PhoneNumber) {
if (input instanceof string) return parsePhoneNumberWithError(input)
return input
}
I have a same problem
There's no "problem"
I have a function that accepts a string as input, at the output I expect either an email or a phone that is parsed into the PhoneNumber object and another Email object, in my case I do NOT receive a string, I would like to know exactly what it is to give a correct error
Not clear. Provide code and examples.
import parsePhoneNumber, { PhoneNumber } from 'libphonenumber-js'
import parseEmail, { Email } from 'email-js'
const getPhoneOrEmailOrNickName = (input: string): PhoneNumber | Email | string => {
const number = parsePhoneNumber(input)
if (number && number.isValid()) {
return number
}
const email = parseEmail(input)
if (email && email.isValid()) {
return email
}
return input // nickname
}
const myAwesomePureFunction = (input: string) => {
const login = getPhoneOrEmailOrNickName(input)
if (login instanceof Email) {
// call send email otp message
} else if (login instanceof PhoneNumber) {
// call send phone number otp message
} else if (typeof login === 'string') {
// Do something with nickname
}
throw 'Something wrong'
}
/*
Yes, I can write the function like this, but it won't work cleanly, i want that front does not fall with an unexpected exception
*/
const myAwesomePureFunction = (input: string) => {
const login = getPhoneOrEmailOrNickName(input)
if (login instanceof Email) {
// call send email otp message
} else if (typeof login === 'string') {
// Do something with nickname
}
// call send phone number otp message
}
So you're using instanceof PhoneNumber
.
The answer is simple:
Change return number
to:
return {
number: number.number,
...
}
Or:
const { email, number, nickname } = getPhoneOrEmailOrNickName()
There's no need to go polymorphic in your case.
Yes, I understand your solution, I just don't understand what is the difficulty in adding a class to the export, thanks
You don't need to use that class. It's not for your use.
I'm too making a universal phone parsing utility, that can accept an unknown
value. Within that utility I need to check for already created PhoneNumber
instance. I can't use PhoneNumber | unknown
as a type, because it still evaluates to unknown
.
export const parsePhone = (rawValue: unknown) => {
if (rawValue instanceof PhoneNumber) return rawValue
const value = convertToString(rawValue)
if (value === undefined) return
return parsePhoneNumberFromString(value)
}
@catamphetamine Please, consider exporting the PhoneNumber
class or providing a utility to check if a value is the class instance.
Wouldn't it be sufficient to just export the PhoneNumber
type instead of the class itself?
import type { PhoneNumber } from 'libphonenumber-js'
The instanceof PhoneNumber
construct wouldn't work in that case, but I heard there's a "type guard" feature in TypeScript that could substitute instanceof
operator:
https://bobbyhadz.com/blog/typescript-instanceof-only-refers-to-type-but-is-being-used-as-value
So seems like there's no need to export the implementation of the PhoneNumber
class from this library. And the PhoneNumber
type is already exported.
Oh, yes, I've got it working using some duck typing and the TypeScript's type guard feature:
import { PhoneNumber } from 'libphonenumber-js'
import { isObject } from 'src/utils'
const isPhone = (value: unknown): value is PhoneNumber =>
isObject(value) &&
'countryCallingCode' in value &&
'nationalNumber' in value &&
'number' in value
const phone: unknown = {}
if (isPhone(phone) && phone.isValid()) {
console.log(phone.formatInternational()) // OK
}
Thanks!
Would it be possible to export the
PhoneNumber
class itself? I have a wrapper function that parses accepts multiple types to cast as aPhoneNumber
:Except
PhoneNumber
is not exported on the package level (only the type definition).