Repository: TypeScript
Issue: Avoid printing out expected/actual types in JSX attributes unless a spread is provided
Labels: Help Wanted,Effort: Moderate,Domain: Error Messages,Experience Enhancement

[Playground link](http://www.typescriptlang.org/play/index.html?jsx=2&ssl=23&ssc=14&pln=23&pc=22#code/JYWwDg9gTgLgBAJQKYEMDGMA0cDecASAKgLIAyAgjDFMAEYCuMSAztsujAHIQAmS2AXzgAzKBBBwA5FFQZJAbgCwAKBUqYATzBI4AUXrAAkmggA7OAF5EsmADoACvRkBhcZFNJTMJauUAeACEUHgBzHU1tCwAiAGJheKiAPhU4OGZ6MBU-AHog0KRk32F6UwxgMzg8sIAKMDEwZgAuSuCw+3rmAEpcFLgZGCdzPx5gADc4bMKBNWUkAA9IWDgInSqkdogGyx7lVOyAKn3euH24cjQ0JDAYZjgUUw006mBTEJExCQgnOGATcwAbOhQFBQDTHfbZXq-MyELRIAD8zWYz1ecAAPtYOLZ2BhdP8kCBPN4ZntDuC4IQABY6ZjAPhwCDCZbUuC0VrhFnQ8zMSlff48NLAGDgyG7H5-ADKdIRzWMZilfB8vQORzFJzOFyuNzgSCF1KgDO+YBQ+KoOhM-2gt1qNBAII02GYSD+PHtcFstiQMDQ3Wgdzg1LmcFGJvoOgABjEAGIx2Ph7CRgAMyfDthFvQt0ERcDlplclqgPlJqtS6oA6sB-v8GaMkFAaPT7o9MwbjcwnQKYJSxPQQpTmRGW+G4HVNmm1RCocwACLAZgoWj4njZ2gQCD4+5KsUq8kbLZtjvLCADuBoS1O1mMGBmcelydis8QJ0BK9mPfMbP2EEwYAmvzvgB5YQ-H0Iw-kSRIfCEAAyOBXBAEA3w6OBoN6XQ5jPehaVrABVUxylMPwKy7XMALzQE0AAa2wHABESFC0Iw-4sLGJA8IIoi9QlY1THfbBiMpF8qCQzZmEgmYVhzP58z9KxkRoV4txeJgoGEdAdAE0jyN+SidmLckKyrO4wDAf5HnuBlSgo3Tr3FCoAHc9ReE82XydMxS5MjnGs5piC+J1dFrLx8HuHh8SgPwiDIITr1MPECSJcTfH0iczhoFA4H+BckGrFATMBJBO2PLsdE87SqMvYTTHc1Iyu8nTyHS0hsv+JEURCKCJLhOABO4+5322ACQCFSKSAoKgaAYJhmFGsg+ri-FCS8RJsEkMx6qoyR0SkFtJCS9RutzBUdCsSR8WEGAtoxaRgD7S6lPAaB4BwXpyFKXkoCi8bnimlhMF6GKzC+ygfsYP7eng9wiX+sUoxKMp1rcMxod6PysKQQKiRC0wwrrGHUglKNnBhoRRHEKQZA4BQZnmRZ4GUus1MuODxEQ3jkJeh8svbTgUEJbN5JeDrekkEFfwAWiy2gcskAX2qLKRXRgFBxemmBxfSWgACtZbahTheUaZfFpp7lm67hGpCZwTX+NkqL8Qh6KsapugsejCC3E2lkk5BhGtqs7cokDFqJHU5iYHHbi++KlvgDFTHoKsnbgapehyhKvGaGOiRUV36NGCA6S3bJsjgRhKyFR4ViaGYd12U4y2BLYAO1507EopANFuRyuxHeo6zN7RmDQGhrjgPhhBeIUCIZJkSr6FhE5-VEQWBMF69FL34GKUofwqDuu6Ah3sAAaTDiOeFuA-GQpRJqggbXmkITpmhPgBtABdPSF4GKBzBbrWbdbAH2YPfbW3QUC3Hfh-TqxsFim0koBYCzhk7OHPp4S+cBCbOD8C8YQA9sHvkKKkeEWCibvl6M0NB8wL63DhrvAikNkZeFwaYfBBp6EI3ZqJYhcBSGcL3twholC4LoMjizR6HgWF4IHkwqRMAiG9FIXIokFCxTNA8LWQstdVSUioA0RoJcQh6noLQWwJgQDZGIL8MQzBGQwGyLCbQEoR7AGuNkOc6QWDZAAEwAA4ADMASACcKgNiLgJM0ewOk7g4zgENIU49jymAgPAEYgtfo1gHiUGe1dsD2UpL8fsdp8L4ORN3ak1VlCbEESaYMoYWCsmdOIHQMgACOBgZAChQBdAeGVokVT9Ak+Amw6woEEbYCk1InQqFnBk8utYRDQBALcEw9Y25mQZNoYETBLJl3whUPJfcWBIFGELLZtTASaFvPeSS7EzAn07jNR22xCBiMwU2PhcBr5MjeRo05dYfBb0HjoOZoMfy1gGUHQgp93m3HuaYR5XcHYQVeXC2J68SFwChcfPQ4dgQYD8D8ikp8IIiM0YClQwLJJgsmgspAwzcVnxoRg+FBzEVPJRcnN5LLxFNiUfE4aMBcXoWoBwIlncb4wrgCfMl6i4AUu0b4A4KgnFIBcaPS6tx0muOGqYcZhV9kEVuCCHQEAtGbO2cNdsrFmiQMymYN49rkYgtnieHJFQ5xpHGXOSehV1AslSfqEFJqZAKtSfUwEStDUoBCCgF4yJJlRj9PMPmpkkCNC6toOAybjxWE5qkEMzEM1PH1vjJZEA9ZCxUAIHwkkggGnzb0ItYYNH0BANLKA5a2RQCra8GtKgd5cLgAU8Z1Q5jNFzdtBt3QC0-0GHAOYtgW1IFgSocgtwNBfBHXyAUtM25wHFjMUdMBqh4BXc0UWzAeDCEkNgYQa5L2QJvVtAQnR5ATFLpPDwKgT1nsja2uAABWe9j6pDPtvXAN9H6S46nrNAX9lIx3noac0EDrIQRPuvZB6Dn6RAvCQIh5DAGS1XpfdgHtWGX1QffXhusYgoAzHwBAeyAKu0-CZFOr184fzMD9Z2SpcAt30FPBZA8GKSNCe3fZe48BbINskLcHJHSdCjm2T+FgmblB-pQ8Wqjt7QOVvA9hu9GHe0iBNBeN9eH7LQEoswGYaqNVuPprcCAlEUCPB7v2LsXr7UZUkiEegIIBS2cTgKPgTAMAngfoA6LXqp2hWOUFeA6BLg2tROGHtqYVB4QfbAEoBrNm+duHUAFXhbj4MKoHI87qnQGgXF8eAkAI4-hto8HJXgiQETqUgeIbdWBLINKm8A+ItPrtPKzCoxozR-x+OYXQOFDA-FuLZGQOMB52MJL5leJrx5jHiQgO4e2pqxWwHwbQONzmeqZBZda1k+6bBWyOSBHZxwHnOcEEYlzHtbB4Cx8wXYex9jgKmD0MhkTxhHYUtA-Y0AWWlmkbQaBgD8eO1mnQ81AQd22MDCadAwYzS+vNbOy063dUBqYbHJ1cCWQ2pRXy-kMYpexrjCKX1Kek5gPRWteH7sxK9fPHVtoXiyZUDiOwAjGFI3kX4LHwAccYkp9TwoKhDBdb-u17A88LFQy8Du8LAYUCLIC91ILIXauw+dLpVHv3VlmGVgm0H-OqLDiSxD9ciz5OvipwrpA45RV1n1VWB0AYWNsewMJybhv0Ynl18w1LDnfB+BUfrld0QGAAC9M9REmDMJLKS4MMYN-yBkFxvj2vnvLnHkluM+r48AGNcT56BeC1AULu7kuhzSywWkqJTsVHGeClg44qRerKyl24oBCQjANSIJA1X0A2WKiyPgtZLRgGwElsLpeODBZD5lVARVMTRZk3-IWJrVssnDCu4camS88BUMiSs1Y1MQDjbs-79lAcr5pDxRTdu+SMO-YXqLwRadIkyVIOgD6VYLG5yMAtmZcP4VyVccIpWYgZyjYaQ645cFQ+WKgI8qAy8bw8wmE2EOgHqpgNcvgEutgUuiMkiRIIETELEuE7KcuPE1O2AyufucqJwooKgdc6oyAv8VBcAhIHaA8IC82cAOE4azWEOoczkbyTocmySbGKQpwby+aUgyMpmkgCBEA+hQOC+r6mhsh2weABh3Yphq0D6Tg+hk8tYZh9c86f8twVh9hUAkg-yWidhrEPhCqbGUGmhm88C3s3UcyfMtAt0wWTAEoXouKOEycc6b89gMh6EmEfAEqW6vy2AxKyRH82YiqNaxcZIrh5AsB9kOoeoA8byfoOE2AE+3WK8DwdwPA32PW1Y0hN888QaA8kkZMEg0s5yZWToXgoRVK4Rcm3UmRzE5BCKSRyc1QbyGIOE3QvKmCsWB6sGtuJUYapqEmPIpqAo0h0sCBC+5gbySWOEAq1QURHasRBqCRwq0qyRKEsh3QGI9xc40RTx8RiRjRt8Hxz8fO+xjkF488hAEoRqnqJq-wlMPAHW+EKmIiqxshZRJYpwyaBo8e8iV+4yk2V2lymy62fABofgA+pg9EfofgKAxCpwrgpgQUjepQ4QaBQ27y5ybIF4am1ooJoU5h6cscGsyOqOvwduKc9g3Q3mTwoUFuZ4OkC4+Iv2dYGmSeJw5hUBF4jkRk1OmyiO6MRUYQ+xW+loqIsp4YcxrBbE7K4YWmmprhkkb0sO0ApAfu2w74OJLpH0gQkC6wHQDJrqlO7pOOVgXp0AlOfpToiiTp3UqeCiyEVg6E-waANpixPpbpfu3BPuoZBQ5hfwyIEieuMAk68MgiCZKeMuqigZ7oHokxsw0xrqEZUAmZEU0q6R+adEaKqEYobZeOw+ROY0bZXO9EsEc6qQNhwgcs+sCsqQLulE2YaMAULOoU4Us0FA700Ao5CsME2KnsTZiCHQOJUZHZlh3ZVgbyvZqQlOA5dK00G5nOIcy0HxE5dO1kS5TOmMwUa5dYj5PuO5vQe59gW4B02aAklOA0Ta245Rd4PUL+xkpk5k5gZgipFUtk88rkYQPwNwOUwgNU75OkjO6M35MArO65HOAFz53OW4KUcFjUv4mULUiFBUx+88dUD2VJBFC5DFKAzU0srUpaQsUEHxjKd5BOD5lFVUo5q0C5V0O0640Ae08gQAA)

```ts
import React, { HTMLAttributes, ReactNode, } from 'react';


type EuiIcon = React.PureComponent;

<Badge type="#fff">
  sup
</Badge>

function Badge(props: BadgeProps) {
  return <div />
}

export type BadgeProps = {
  /**
   * Accepts any string from our icon library
   */
  iconType?: string | React.ReactElement;

  /**
   * The side of the badge the icon should sit
   */
  iconSide?: IconSide;

  /**
   * Accepts either our palette colors (primary, secondary ..etc) or a hex value `#FFFFFF`, `#000`.
   */
  color?: IconColor;
  /**
   * Will override any color passed through the `color` prop.
   */
  isDisabled?: boolean;

  /**
   * Props passed to the close button.
   */
  closeButtonProps?: Partial<PropsOf<EuiIcon>>;
} & CommonProps &
  ExclusiveUnion<WithIconOnClick, {}> &
  ExclusiveUnion<WithSpanProps, WithButtonProps>;

type IconColor = string;

interface WithIconOnClick {
  /**
   * Will apply an onclick to icon within the badge
   */
  iconOnClick: MouseEventHandler<HTMLButtonElement>;

  /**
   * Aria label applied to the iconOnClick button
   */
  iconOnClickAriaLabel: string;
}

type WithSpanProps = Omit<HTMLAttributes<HTMLSpanElement>, 'onClick' | 'color'>;

type IconSide = 'left' | 'right';

import {
  AnchorHTMLAttributes,
  ButtonHTMLAttributes,
  Component,
  FunctionComponent,
  MouseEventHandler,
  SFC,
} from 'react';

export interface CommonProps {
  className?: string;
  'aria-label'?: string;
  'data-test-subj'?: string;
}

export type PropsOf<C> = C extends SFC<infer SFCProps>
  ? SFCProps
  : C extends FunctionComponent<infer FunctionProps>
  ? FunctionProps
  : C extends Component<infer ComponentProps>
  ? ComponentProps
  : never;

type UnionKeys<T> = T extends any ? keyof T : never;
export type DistributivePick<T, K extends UnionKeys<T>> = T extends any
  ? Pick<T, Extract<keyof T, K>>
  : never;
export type DistributiveOmit<T, K extends UnionKeys<T>> = T extends any
  ? Omit<T, Extract<keyof T, K>>
  : never;

/**
 * Returns member keys in U not present in T set to never
 * T = { 'one', 'two', 'three' }
 * U = { 'three', 'four', 'five' }
 * returns { 'four': never, 'five': never }
 */
export type DisambiguateSet<T, U> = {
  [P in Exclude<keyof T, keyof U>]?: never
};

/**
 * Allow either T or U, preventing any additional keys of the other type from being present
 */
export type ExclusiveUnion<T, U> = (T | U) extends object // if there are any shared keys between T and U
  ? (DisambiguateSet<T, U> & U) | (DisambiguateSet<U, T> & T) // otherwise the TS union is already unique
  : T | U;

type WithButtonProps = {
  /**
   * Will apply an onclick to the badge itself
   */
  onClick: MouseEventHandler<HTMLButtonElement>;

  /**
   * Aria label applied to the iconOnClick button
   */
  onClickAriaLabel: string;
} & Omit<HTMLAttributes<HTMLButtonElement>, 'onClick' | 'color'>;
```

## Current

```
Type '{ children: string; type: string; }' is not assignable to type '(IntrinsicAttributes & { iconType?: string | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<...>)> | undefined; iconSide?: "left" | ... 1 more ... | undefined; color?: string | undefined; isDisabled...'.
  Property 'type' does not exist on type '(IntrinsicAttributes & { iconType?: string | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<...>)> | undefined; iconSide?: "left" | ... 1 more ... | undefined; color?: string | undefined; isDisabled...'.(2322)
```

## Proposed

```
The 'Badge' tag does not accept any attribute named 'type'.
```