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

Types of property 'value' are incompatible. Type 'string' is not assignable to type 'E164Number' #28

Closed
Yokohmariam opened this issue May 11, 2024 · 17 comments · Fixed by #43

Comments

@Yokohmariam
Copy link

First this is awesome i love it.

But when i try to use the example code The input form is throwing this error

Type '{ onChange: (...event: any[]) => void; onBlur: Noop; value: string; disabled?: boolean | undefined; name: "phone"; ref: RefCallBack; placeholder: string; }' is not assignable to type 'Omit<Props<PhoneInputWithCountrySelectType>, "onChange">'.
Types of property 'value' are incompatible.
Type 'string' is not assignable to type 'E164Number'.ts(2322)
(alias) const PhoneInput: React.ForwardRefExoticComponent
import PhoneInput

Screenshot 2024-05-11 at 8 14 46 in the evening
@thallysondias
Copy link

thallysondias commented May 11, 2024

+1

@alex-dnr
Copy link

My mistake was that my editor auto imported Form component from react-hook-form when it should have been imported from @/components/ui/form. 👀

@Yokohmariam
Copy link
Author

still am getting same error

@femiorok
Copy link

Added some basic type conversion and it worked for me.

onChange={(value) => onChange?.(value || ('' as RPNInput.Value))}

@owencage
Copy link

still am getting same error

Did you manage to get it sorted?

@Yokohmariam
Copy link
Author

Yokohmariam commented May 13, 2024

still am getting same error

Did you manage to get it sorted?
i have built new from scratch to use with react-hook-form

this is the phone-input component ready to use with react-hook-form


import "react-phone-number-input/style.css";
import * as RPNInput from "react-phone-number-input";
import { forwardRef, useCallback } from "react";
import { Control, FieldValues, Path } from "react-hook-form";

import flags from "react-phone-number-input/flags";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Button } from "./ui/button";
import { CheckIcon, ChevronsUpDown } from "lucide-react";
import { cn } from "@/lib/utils";
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from "@/components/ui/command";
import { ScrollArea } from "./ui/scroll-area";
import { InputProps } from "./ui/input";
import {
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "./ui/form";

interface PhoneProps<TFormValues extends FieldValues> {
  name: Path<TFormValues>;
  control: Control<TFormValues> | undefined;
  label: string;
  placeholder: string;
}

const Phone = <TFormValues extends FieldValues>({
  name,
  control,
  label,
  placeholder,
}: PhoneProps<TFormValues>) => {
  return (
    <FormField
      control={control}
      name={name}
      render={({ field }) => (
        <FormItem>
          <FormLabel className="text-kblack-text text-[16px]" htmlFor={name}>
            {label}
          </FormLabel>
          <FormControl>
            <RPNInput.default
              defaultCountry="ET"
              className={cn("flex")}
              flagComponent={FlagComponent}
              countrySelectComponent={CountrySelect}
              inputComponent={InputComponent}
              placeholder={placeholder}
              {...field}
            />
          </FormControl>
          <FormMessage />
        </FormItem>
      )}
    />
  );
};

export default Phone;

const FlagComponent = ({ country, countryName }: RPNInput.FlagProps) => {
  const Flag = flags[country];

  return (
    <span className="flex h-4 w-6 overflow-hidden rounded-sm ">
      {Flag && <Flag title={countryName} />}
    </span>
  );
};
FlagComponent.displayName = "FlagComponent";

type CountrySelectOption = { label: string; value: RPNInput.Country };

type CountrySelectProps = {
  disabled?: boolean;
  value: RPNInput.Country;
  onChange: (value: RPNInput.Country) => void;
  options: CountrySelectOption[];
};

const CountrySelect = ({
  disabled,
  value,
  onChange,
  options,
}: CountrySelectProps) => {
  const handleSelect = useCallback(
    (country: RPNInput.Country) => {
      onChange(country);
    },
    [onChange]
  );

  return (
    <Popover>
      <PopoverTrigger asChild>
        <Button
          type="button"
          variant={"outline"}
          className={cn(
            "flex gap-1 rounded-e-none rounded-s-lg px-3 bg-kinput-bg border-0 py-6"
          )}
          disabled={disabled}
        >
          <FlagComponent country={value} countryName={value} />
          <ChevronsUpDown
            className={cn(
              "-mr-2 h-4 w-4 opacity-50",
              disabled ? "hidden" : "opacity-100"
            )}
          />
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-[300px] p-0">
        <Command>
          <CommandList>
            <ScrollArea className="h-72">
              <CommandInput placeholder="Search country..." />
              <CommandEmpty>No country found.</CommandEmpty>
              <CommandGroup>
                {options
                  .filter((x) => x.value)
                  .map((option) => (
                    <CommandItem
                      className="gap-2"
                      key={option.value}
                      onSelect={() => handleSelect(option.value)}
                    >
                      <FlagComponent
                        country={option.value}
                        countryName={option.label}
                      />
                      <span className="flex-1 text-sm">{option.label}</span>
                      {option.value && (
                        <span className="text-sm text-foreground/50">
                          {`+${RPNInput.getCountryCallingCode(option.value)}`}
                        </span>
                      )}
                      <CheckIcon
                        className={cn(
                          "ml-auto h-4 w-4",
                          option.value === value ? "opacity-100" : "opacity-0"
                        )}
                      />
                    </CommandItem>
                  ))}
              </CommandGroup>
            </ScrollArea>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
};

const InputComponent = forwardRef<HTMLInputElement, InputProps>(
  ({ className, ...props }, ref) => (
    <input
      name={props.name}
      className="outline-none rounded-r-md w-full  px-4 py-3 bg-kinput-bg flex-initial"
      placeholder="Phone number"
      {...props}
      ref={ref}
    />
  )
);
InputComponent.displayName = "InputComponent";

so you can use it like this easly inside your component

<Phone
          name={"phone"}
          control={form.control}
          label={"Phone Number"}
          placeholder={"Phone number"}
        />

make your sure to include the phone validation

 import { isValidPhoneNumber } from "react-phone-number-input";
   phone: z
      .string()
      .refine(isValidPhoneNumber, { message: "Invalid phone number" }), 

@abuu-u
Copy link

abuu-u commented May 14, 2024

onChange={(value) =>
  onChange?.(
    value ||
      Object.assign<"", { __tag: "E164Number" }>("", {
        __tag: "E164Number",
      })
  )
}

@jjppsia
Copy link

jjppsia commented May 14, 2024

I encountered the same type of error. I believe it's due to the fact that the react-phone-number-input package utilizes the latest version of libphonenumber-js, which has a different type value for E164Number.

Screenshot 2024-05-14 212241

To address this issue temporarily, I included libphonenumber-js as a dependency and specified its version as 1.10.61 to revert to the previous type value for E164Number.

Screenshot 2024-05-14 212547

@1Mouse
Copy link

1Mouse commented May 16, 2024

@jjppsia yeah this version is supposed to solve the issue I saw the channel log on gitlab
how did you manage to force react-phone-number-input 3.4.1 to use libphonenumber-js 1.10.61 ?

@1Mouse
Copy link

1Mouse commented May 16, 2024

@jjppsia yeah this version is supposed to solve the issue I saw the channel log on gitlab how did you manage to force react-phone-number-input 3.4.1 to use libphonenumber-js 1.10.61 ?

I tried this but react-phone-number-input still uses version 1.11.1

  "overrides": {
    "react-phone-number-input": {
      "dependencies": {
        "libphonenumber-js": "1.10.61"
      }
    }
  },
  

@jjppsia
Copy link

jjppsia commented May 16, 2024

oh i npm i libphonenumber-js@1.10.61 and deleted both my node_modules and package-lock.json and installed them again.

@1Mouse
Copy link

1Mouse commented May 16, 2024

@jjppsia thanks for the quick response

overrides doesn't work with yarn so I used resolutions and everything now works

  "resolutions": {
    "react-phone-number-input/libphonenumber-js": "1.10.61"
  }

@ezevic
Copy link

ezevic commented May 17, 2024

@jjppsia thanks for the quick response

overrides doesn't work with yarn so I used resolutions and everything now works

  "resolutions": {
    "react-phone-number-input/libphonenumber-js": "1.10.61"
  }

does not work for me

@1Mouse
Copy link

1Mouse commented May 19, 2024

@ezevic
try deleting node modules besides the resolution

@ezevic
Copy link

ezevic commented May 20, 2024

@ezevic
try deleting node modules besides the resolution

I did a clean install of the project's dependencies. I also checked the libphonenumber-js package version and it is 1.10.61

@1Mouse
Copy link

1Mouse commented May 20, 2024

@ezevic
try deleting node modules besides the resolution

I did a clean install of the project's dependencies. I also checked the libphonenumber-js package version and it is 1.10.61

u checked it in your package json or in the package json of react-phone-number-input in node_modules?
u need to make sure that installed version of react-phone-number-input uses libphonenumber-js 1.10.61
as it could be 1.10.61 in your package json but the react-phone-number-input uses another version behind the scenes

@ezevic
Copy link

ezevic commented May 20, 2024

@ezevic
try deleting node modules besides the resolution

I did a clean install of the project's dependencies. I also checked the libphonenumber-js package version and it is 1.10.61

u checked it in your package json or in the package json of react-phone-number-input in node_modules?
u need to make sure that installed version of react-phone-number-input uses libphonenumber-js 1.10.61
as it could be 1.10.61 in your package json but the react-phone-number-input uses another version behind the scenes

I checked in the package json of react-phone-number-input

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

Successfully merging a pull request may close this issue.

9 participants