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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(types): expose ElementAttributesProperty for TSX #9379

Open
wants to merge 1 commit into
base: dev
from

Conversation

Projects
None yet
2 participants
@andoshin11
Copy link

andoshin11 commented Jan 27, 2019

What kind of change does this PR introduce? (check at least one)

  • Bugfix
  • Feature
  • Code style update
  • Refactor
  • Build-related changes
  • Other, please describe:

Does this PR introduce a breaking change? (check one)

  • Yes
  • No

If yes, please describe the impact and migration path for existing applications:

The PR fulfills these requirements:

If adding a new feature, the PR's description includes:

  • A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

Descriptions

With current type definitions, it's extremely difficult for developers to pass props to children components when writing TSX since there's no exposed property that JSX can handle as element attributes properties.

2019-01-27 22 45 39

This PullRequest achieves 2 things.

  • Creates new property _attrs to the ExtendedVue type so it can be used inside JSX.ElementAttributesProperty.(Examples are below)
  • Transform non-required props into optional properties of props interface.

Example

Given these 2 children components...

// PrimaryButton.tsx
import Vue from 'vue'

export default Vue.extend({
  name: 'Primary Button',
  props: {
    label: {
      type: String,
      required: true as true
    },
    color: String
  },
  computed: {
    style(): string {
      return `color: ${this.color || 'blue'};`
    }
  },
  render() {
    return <button style={this.style}>{this.label}</button>
  }
})
// SecondaryButton.tsx
import Vue from 'vue'

export default Vue.extend({
  name: 'Secondary Button',
  props: ['color', 'label'],
  computed: {
    style(): string {
      return `color: ${this.color || 'blue'};`
    }
  },
  render() {
    return <button style={this.style}>{this.label}</button>
  }
})

and prepare shims-tsx.d.ts like this

// shims-tsx.d.ts
import Vue, { VNode } from 'vue'

declare global {
  namespace JSX {
    interface Element extends VNode {}
    interface ElementClass extends Vue {}
    interface ElementAttributesProperty {
      _attrs: any
    }
    interface IntrinsicElements {
      [elem: string]: any
    }
  }
}

Property completion works as expected.

2019-01-27 22 55 58

Type error warned as expected.

2019-01-27 22 56 15

and no more errors with correct props declaration 馃憤

2019-01-27 23 00 09

@andoshin11 andoshin11 force-pushed the andoshin11:feature/extract-outer-props-type branch from afa69a4 to 9a38c4f Jan 27, 2019

@andoshin11

This comment has been minimized.

Copy link
Author

andoshin11 commented Jan 27, 2019

oops... fixing errors

@andoshin11 andoshin11 referenced this pull request Jan 27, 2019

Merged

chore(examples): Add tsx example #4855

1 of 7 tasks complete
@ktsn

This comment has been minimized.

Copy link
Member

ktsn commented Feb 7, 2019

Thanks for your amazing work! I briefly looked into it and it would be so useful for TSX users!
Only thing I'm concerning is that it will make type parameters of component more complicated. I'm not sure if we can directly declare the required/optional info into Props type parameter but I think it is ideal. I'll take a look if we can simplify the type declaration more.

As a side note, in Vue v3, we can declare Props type by hand. So we may include required/optional info in Props type directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment