Skip to content

Commit

Permalink
fix(types): augment ref unwrap bail types in appropriate packages
Browse files Browse the repository at this point in the history
Packages can now augment the ref unwrap bail types in their own `d.ts`.
Also updated the build script to auto concat any files in a package's
`types` directory to the final generated `d.ts`.

- `@vue/reactivity` should no longer require `libs: ["DOM"]` in tsconfig
- Properly bail on `VNode` and `ComponentPublicInstance` in runtime-core
  • Loading branch information
yyx990803 committed May 1, 2020
1 parent 7f23555 commit b40fcbc
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 12 deletions.
3 changes: 2 additions & 1 deletion packages/reactivity/src/index.ts
Expand Up @@ -9,7 +9,8 @@ export {
triggerRef,
Ref,
UnwrapRef,
ToRefs
ToRefs,
RefUnwrapBailTypes
} from './ref'
export {
reactive,
Expand Down
28 changes: 26 additions & 2 deletions packages/reactivity/src/ref.ts
Expand Up @@ -139,13 +139,37 @@ export function toRef<T extends object, K extends keyof T>(
// corner case when use narrows type
// Ex. type RelativePath = string & { __brand: unknown }
// RelativePath extends object -> true
type BaseTypes = string | number | boolean | Node | Window
type BaseTypes = string | number | boolean

/**
* This is a special exported interface for other packages to declare
* additional types that should bail out for ref unwrapping. For example
* \@vue/runtime-dom can declare it like so in its d.ts:
*
* ``` ts
* declare module '@vue/reactivity' {
* export interface RefUnwrapBailTypes {
* runtimeDOMBailTypes: Node | Window
* }
* }
* ```
*
* Note that api-extractor somehow refuses to include `decalre module`
* augmentations in its generated d.ts, so we have to manually append them
* to the final generated d.ts in our build process.
*/
export interface RefUnwrapBailTypes {}

export type UnwrapRef<T> = T extends ComputedRef<infer V>
? UnwrapRefSimple<V>
: T extends Ref<infer V> ? UnwrapRefSimple<V> : UnwrapRefSimple<T>

type UnwrapRefSimple<T> = T extends Function | CollectionTypes | BaseTypes | Ref
type UnwrapRefSimple<T> = T extends
| Function
| CollectionTypes
| BaseTypes
| Ref
| RefUnwrapBailTypes[keyof RefUnwrapBailTypes]
? T
: T extends Array<any> ? T : T extends object ? UnwrappedObject<T> : T

Expand Down
17 changes: 17 additions & 0 deletions packages/runtime-core/src/index.ts
Expand Up @@ -87,6 +87,23 @@ export {

// Types -----------------------------------------------------------------------

import { VNode } from './vnode'
import { ComponentInternalInstance } from './component'

// Augment Ref unwrap bail types.
// Note: if updating this, also update `types/refBail.d.ts`.
declare module '@vue/reactivity' {
export interface RefUnwrapBailTypes {
runtimeCoreBailTypes:
| VNode
| {
// directly bailing on ComponentPublicInstance results in recursion
// so we use this as a bail hint
$: ComponentInternalInstance
}
}
}

export {
ReactiveEffect,
ReactiveEffectOptions,
Expand Down
14 changes: 14 additions & 0 deletions packages/runtime-core/types/refBail.d.ts
@@ -0,0 +1,14 @@
// Note: this file is auto concatenated to the end of the bundled d.ts during
// build.

declare module '@vue/reactivity' {
export interface RefUnwrapBailTypes {
runtimeCoreBailTypes:
| VNode
| {
// directly bailing on ComponentPublicInstance results in recursion
// so we use this as a bail hint
$: ComponentInternalInstance
}
}
}
3 changes: 0 additions & 3 deletions packages/runtime-dom/package.json
Expand Up @@ -18,9 +18,6 @@
"esm-browser",
"cjs",
"global"
],
"dts": [
"jsx.d.ts"
]
},
"repository": {
Expand Down
7 changes: 7 additions & 0 deletions packages/runtime-dom/src/index.ts
Expand Up @@ -14,6 +14,13 @@ import { patchProp } from './patchProp'
// Importing from the compiler, will be tree-shaken in prod
import { isFunction, isString, isHTMLTag, isSVGTag } from '@vue/shared'

declare module '@vue/reactivity' {
export interface RefUnwrapBailTypes {
// Note: if updating this, also update `types/refBail.d.ts`.
runtimeDOMBailTypes: Node | Window
}
}

const rendererOptions = {
patchProp,
...nodeOps
Expand Down
@@ -1,3 +1,6 @@
// Note: this file is auto concatenated to the end of the bundled d.ts during
// build.

import { Ref, ComponentPublicInstance } from '@vue/runtime-core'

// This code is based on react definition in DefinitelyTyped published under the MIT license.
Expand Down
8 changes: 8 additions & 0 deletions packages/runtime-dom/types/refBail.d.ts
@@ -0,0 +1,8 @@
// Note: this file is auto concatenated to the end of the bundled d.ts during
// build.

declare module '@vue/reactivity' {
export interface RefUnwrapBailTypes {
runtimeDOMBailTypes: Node | Window
}
}
10 changes: 6 additions & 4 deletions scripts/build.js
Expand Up @@ -107,13 +107,15 @@ async function build(target) {
})

if (extractorResult.succeeded) {
// concat additional d.ts to rolled-up dts (mostly for JSX)
if (pkg.buildOptions && pkg.buildOptions.dts) {
// concat additional d.ts to rolled-up dts
const typesDir = path.resolve(pkgDir, 'types')
if (await fs.exists(typesDir)) {
const dtsPath = path.resolve(pkgDir, pkg.types)
const existing = await fs.readFile(dtsPath, 'utf-8')
const typeFiles = await fs.readdir(typesDir)
const toAdd = await Promise.all(
pkg.buildOptions.dts.map(file => {
return fs.readFile(path.resolve(pkgDir, file), 'utf-8')
typeFiles.map(file => {
return fs.readFile(path.resolve(typesDir, file), 'utf-8')
})
)
await fs.writeFile(dtsPath, existing + '\n' + toAdd.join('\n'))
Expand Down
5 changes: 3 additions & 2 deletions tsconfig.json
Expand Up @@ -19,13 +19,14 @@
"rootDir": ".",
"paths": {
"@vue/*": ["packages/*/src"],
"vue": ["packages/vue/src"]
"vue": ["packages/vue/src"],
"@vue/reavitity": ["packages/reactivity/src/index.ts"]
}
},
"include": [
"packages/global.d.ts",
"packages/runtime-dom/jsx.d.ts",
"packages/*/src",
"packages/runtime-dom/types/jsx.d.ts",
"packages/*/__tests__",
"test-dts"
]
Expand Down

0 comments on commit b40fcbc

Please sign in to comment.