CyCraft / CyCraft/blitzar

Improve prop types

Open
#111 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Vue
Stars
126
Forks
22
PR merge metrics
No merged PRs in 30d

Description

- [x] BlitzTable
- [x] BlitzField
- [ ] BlitzForm

---

@mesqueeb This is possible with a bit of type magic, yes.

```ts
import {
ExtractPropTypes,
ExtractDefaultPropTypes,
} from 'vue'
import { SetOptional } from 'type-fest'

export type ExternalProps>
= SetOptional, keyof ExtractDefaultPropTypes>
```
Usage:
```ts
import { ExternalProps } from './typeUtils.ts'
import { PropTypes } from 'vue'
// Example custom types
interface User {
name: string
}
interface Post {
title: string
}

const mySharedProps = {
user: {
type: Object as PropType,
default: () => ({ name: 'Tom' })
},
post: {
type: Object as PropType,
required: true,
},
} as const // <= THIS IS NECESSARY TO DETECT REQUIRED PROPS CORRECTLY!

export type MySharedProps = ExternalProps

//This is the resulting type:
type MySharedProps = {
user?: User | undefined // has default value internally, but from parent's perspective it's optional
post: Post // required
}
```

A little bit on how this works:

`ExtractPropTypes` gives you almost what you want, but the resulting interface has props with a default value marked as required. This is because this interface is the *internal* props interface - `this.$props`, where props with default values are guaranteed to be present.

So we need to make these optional. How?

* `ExtractDefaultPropTypes` gives us an interface with only those props that have default values
* We then use the keys of this interface with `keyof` ...
* and make these keys optional on the interface provided by `ExtractPropTypes`

For the last step I use `SetOptional` from the amazing [`type-fest`](https://github.com/sindresorhus/type-fest) collection of useful types, but I'm sure there's a SO answer out there that explains how to make properties on an interface optional if you don't want to add another dependency.

Also, yes - I think it would make real sense to have this in the core types.

__Originally posted by @LinusBorg in https://github.com/vuejs/core/issues/4294#issuecomment-1030594118__

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.