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

Typescript does not explicitly pass undefined, which breaks intelliSense [5.5.2] #58976

Closed
MrOxMasTer opened this issue Jun 23, 2024 · 10 comments
Labels
Not a Defect This behavior is one of several equally-correct options

Comments

@MrOxMasTer
Copy link

MrOxMasTer commented Jun 23, 2024

🔎 Search Terms

Typescript does not explicitly pass undefined, which breaks intelliSense

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about "Typescript does not explicitly pass undefined, which breaks intelliSense"

⏯ Playground Link

https://codesandbox.io/p/devbox/test-typescript-q89n2h

💻 Code

import Link from "next/link";
import { ComponentProps } from "react";

type HTMLButtonProps = ComponentProps<"button"> & {
  href?: undefined;
};

type HTMLLinkProps = ComponentProps<typeof Link>;

type buttonAndLink = HTMLButtonProps | HTMLLinkProps;
type actionProps = buttonAndLink;

export const Action = ({
  //  intent, size,
  ...props
}: actionProps) => {
  if (typeof props.href !== "undefined") {
    const { className, ...rest } = props;

    return (
      <Link
        // className={cn(actionVariants({ intent, size, className }))}
        // {...rest}
        {...rest}
      />
    );
  }

  const { className, ...rest } = props;

  return (
    <button
      // className={cn(actionVariants({ intent, size, className }))}
      {...rest}
    />
  );
};

🙁 Actual behavior

Without explicitly specifying href={undefined}, conditional types do not work

🙂 Expected behavior

Instead of the typical: "button" | "submit" | "reset" | undefined
I get the type: string | undefined

Additional information about the issue

Let's move on. Why do I lose button typing if I don't have an href?
image

For some reason, button types are shown here only if undefined is explicitly specified
image
It may then open up a new issue for this problem that typescript does not implicitly define undefined (props that do not pass)

It determines if there is some kind of internal typing, but it is not displayed when opening intelliSense:
image

@jcalz
Copy link
Contributor

jcalz commented Jun 23, 2024

NOTE WELL: I'm not a member of the TS team, just a nosyhelpful bystander.

If you're trying to report a bug in the TypeScript language, you should make an effort to reproduce it with a small self-contained example, one that fits in a single file and does not need to pull in type definitions from other libraries like react or next. Codesandbox is not the TS playground. The vast majority of bugs can be demonstrated in just a few lines of code.

If you're just having trouble with using TypeScript along with these other technologies, you should consider closing this and opening a question of Stack Overflow or in the TypeScript discord channel. Then, assuming you follow their guidelines and someone responds, if it turns out that the problem really is a bug in TypeScript you might be directed back here with a truly minimal example, or someone might point to an existing bug (like maybe #38849 or #50139) so you can track the progress (or lack thereof) there.

You mention "conditional types" but there are no conditional types here. You presumably mean union types instead. Your search terms just look like your title, indicating maybe you didn't really search first? If you search for "react union intellisense", do any of the results look like your problem?

@RyanCavanaugh RyanCavanaugh added the Not a Defect This behavior is one of several equally-correct options label Jun 24, 2024
@RyanCavanaugh
Copy link
Member

I'm not really seeing a bug demonstrated here

@MrOxMasTer
Copy link
Author

MrOxMasTer commented Jun 24, 2024

I'm not really seeing a bug demonstrated here

That is, logically, I always need to explicitly specify undefined for each props so that I can display types in intelliSense under this condition:

if (typeof props.href !== "undefined")

After all, undefined is always passed there by default, if there is no defined props. The question is, why is this done?

@MrOxMasTer
Copy link
Author

MrOxMasTer commented Jun 24, 2024

it would be normal if it simply did not define and, for example, with the value "a", it would not give an error. So why, if it defines the necessary types, not output them in intelliSense?

@MrOxMasTer
Copy link
Author

MrOxMasTer commented Jun 25, 2024

By the way, here's another moment from issue #38849. I don't explicitly specify href and the types work for me, but they don't work in jsx
image
image

@MrOxMasTer
Copy link
Author

I'm not really seeing a bug demonstrated here

Also, after a couple of actions, intelliSense will stop working for calling the function:
https://github.com/microsoft/TypeScript/assets/59291123/e79db2b9-e012-487f-9b04-c2902c8a5825

image
image

@MartinJohns
Copy link
Contributor

I'm not really seeing a bug demonstrated here

He expects the absence of the href property to be used for narrowing, so that the props are narrowed to HTMLButtonProps, which has a limited type for type including only three specific strings (unlike the link-props, where it's string). When having an explicitly set href it is being narrowed for auto-completion purposes.

Here's a simplified example: Playground

Auto completion for type works in line 9, but in line 10 it does not work.

@MrOxMasTer
Copy link
Author

MrOxMasTer commented Jun 25, 2024

He expects the absence of the href property to be used for narrowing, so that the props are narrowed to HTMLButtonProps, which has a limited type for type including only three specific strings (unlike the link-props, where it's string). When having an explicitly set href it is being narrowed for auto-completion purposes.

I understand that, yes, but just undefined is always passed by default in the component if there are no props. From my point of view, I understand that this is not critical, but it is inconvenient that you need to explicitly specify undefined. Rather, it makes no sense to specify undefined for props.

@MrOxMasTer
Copy link
Author

MrOxMasTer commented Jun 25, 2024

He expects the absence of the href property to be used for narrowing, so that the props are narrowed to HTMLButtonProps, which has a limited type for type including only three specific strings (unlike the link-props, where it's string). When having an explicitly set href it is being narrowed for auto-completion purposes.

In the playground, in your example, such a thing does not appear:
image

Although it is much more logical and better than that:
image

I don't know, I don't think this is really convenient, and it would be better to fix it, because if props was not passed, it is equal to undefined by default.

Although the default values were indicated in this issue #50139. I hope undefined will be included in these default values

@typescript-bot
Copy link
Collaborator

This issue has been marked as "Not a Defect" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Not a Defect This behavior is one of several equally-correct options
Projects
None yet
Development

No branches or pull requests

5 participants