npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@icare-jp/vue-props-type

v0.0.22

Published

vue-props-type

Downloads

3,647

Readme

Vue Props Type

Vue Props TypeVue.jspropsの型定義を助けます.

Why

composition-apiを利用したコードを書く場合、以下のように書く必要があります.

import { defineComponent } from '@vue/composition-api'

export type HogeHogeProps = {
  A: 'github' | 'qiita' | 'facebook'
  B: 0 | 1 | Date
  C: { label: string, value: string }
  D: string[]
  E: string | number
  F: (key: string, value: string) => void
}

export default defineComponent<HogeHogeProps>({
  name: 'HogeHoge',
  props: {
    A: {
      type: String,
      default: () => 'github'
    },
    B: {
      type: [Number, Date],
      required: true,
    },
    C: {
      type: Object,
      required: true,
    },
    D: {
      type: Array,
      required: true,
    },
    E: [String, Number],
    F: Function,
  },
  setup(props) {
    // props is type safe
  },
})

Optionに渡すprops objectと型定義のProps typeは別々で定義されおり、素直に書く場合は、人の手により両方をメンテナンスする必用があります. これには課題があり、もしprops objectのコードを変更し、Props typeの修正を忘れた場合、HogeHogeProps type又はprops objectは嘘をつくことになります. 人によってはprops objectの項目が多い場合、Props typeの型定義をサボりたくなるでしょう. 人によってはsetup内でアクセスしているprops objectの項目の型定義しか書かない可能性もあります. 以下がその例です.

import { defineComponent } from '@vue/composition-api'

export type HogeHogeProps = {
  A: 'github' | 'qiita' | 'facebook'
}

export default defineComponent<HogeHogeProps>({
  name: 'HogeHoge',
  props: {
    A: {
      type: String,
      default: () => 'github'
    },
    B: {
      type: [Number, Date],
      required: true,
    },
    C: {
      type: Object,
      required: true,
    },
    D: {
      type: Array,
      required: true,
    },
    E: [String, Number],
    F: Function,
  },
  setup(props) {
    // Props type is { A: string }
    console.log(props.A)
  },
})

しかもこの例では少なくともDEFがどんな模様の型なのか一切わかりません. templateの中でどのようにアクセスされているのでしょうか? 我々がその模様を知りたい場合、そこから読み解く必用があります. 我々の気合による推論で消費する時間は多いのに対して、型定義でサボって得られる時間はごくわずかです. しかも我々の推論結果が実装者の意図とただしくない可能性があります.

また、サボった場合は、Typescriptのエコシステムの恩恵を正しく受けれなくなるリスクがあります. (例: templateの型検査等 Vue Props TypeはTypeScriptの力によって、このような課題の解決をシンプル且つ簡単に解決することを目指します. 以下がVue Props Typeを使ったサンプルです.

import { defineComponent } from '@vue/composition-api'
import { InsidePropsType, OutsidePropsType, PropType } from '@icare-jp/vue-props-type'

const propsType = {
  A: {
    type: String as PropType<'github' | 'qiita' | 'facebook'>,
    default: () => 'github'
  },
  B: {
    type: [Number, Date] as PropType<0 | 1 | Date>,
    required: true,
  },
  C: {
    type: Object as PropType<{ label: string, value: string }>,
    required: true,
  },
  D: {
    type: Array as PropType<string[]>,
    required: true,
  },
  E: [String, Number],
  F: Function as (key: string, value: string) => void
} as const

export type HogeHogeProps = OutsidePropsType<typeof propsType>
// {
//   A?: string | undefined;
//   B: 0 | Date | 1;
//   C: Readonly<{
//     label: string;
//     value: string;
//   }>;
//   D: string[];
//   E?: string | number | undefined;
//   F?: ((key: string, value: string) => void) | undefined;
// }

type InsideHogeHogeProps = InsidePropsType<typeof propsType>
// {
//   readonly A: string;
//   readonly B: 0 | Date | 1;
//   readonly C: Readonly<{
//     label: string;
//     value: string;
//   }>;
//   readonly D: readonly string[];
//   readonly E: string | number | undefined;
//   readonly F: ((key: string, value: string) => void) | undefined;
// }

export default defineComponent<InsideHogeHogeProps>({
  name: 'HogeHoge',
  props: propsType,
  setup(props) {
    // props is type safe
  },
})

InsidePropsType を使う事により、 props の管理を楽にし、型定義を書くストレスを軽減します. また、 Vue.jsprops へ変更を加える操作を禁止しています. そのため、 props を標準で readonly にしています. もし readonly にすることにより何かしらの問題が起こる場合は UnsafePropsType を利用してください. また、 required: truedefault: () => any も無い場合、 undefined を混ぜています. また、 default: () => any がある場合は戻り値を抽出し、混ぜています. それにより、より実行結果に近い、つまり真実に近い型を得られます.

また、用意されたコンポーネントを利用する側がtype safeにpropsを用意したい場合、以下のようなコードを手動で書き、用意しなければなりません.

export type HogeHogeProps = {
  A?: string | undefined;
  B: 0 | Date | 1;
  C: Readonly<{
    label: string;
    value: string;
  }>;
  D: string[];
  E?: string | number | undefined;
  F?: ((key: string, value: string) => void) | undefined;
}

InsideHogeHogePropsと全く同じ様にOutsidePropsTypeを利用すれば、この型を自動で生成でき、型定義を書くストレスを軽減します. 些細な意見でも結構ですので、なにかありましたら気軽にissueを立てて申し立ててくださると幸いです.