Skip to content
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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: update to Typescript 3.9 #1106

Merged
merged 14 commits into from
Jun 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"lint": "prettier --write --parser typescript \"packages/**/*.ts?(x)\"",
"ls-lint": "ls-lint",
"test": "node scripts/build.js vue -f global -d && jest",
"test-dts": "node scripts/build.js shared reactivity runtime-core runtime-dom -dt -f esm-bundler && tsd",
"test-dts": "node scripts/build.js shared reactivity runtime-core runtime-dom -dt -f esm-bundler && tsc -p ./test-dts/tsconfig.json && tsc -p ./test-dts/tsconfig.build.json",
"release": "node scripts/release.js",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"dev-compiler": "npm-run-all --parallel \"dev template-explorer\" serve",
Expand Down Expand Up @@ -70,8 +70,7 @@
"semver": "^6.3.0",
"serve": "^11.3.0",
"ts-jest": "^25.2.1",
"tsd": "^0.11.0",
"typescript": "^3.8.3",
"typescript": "^3.9.3",
"yorkie": "^2.0.0"
}
}
8 changes: 4 additions & 4 deletions packages/runtime-core/src/componentOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ export interface ComponentOptionsBase<

// type-only differentiator to separate OptionWithoutProps from a constructor
// type returned by defineComponent() or FunctionalComponent
call?: never
call?: (this: unknown, ...args: unknown[]) => never
// type-only differentiators for built-in Vnode types
__isFragment?: never
__isTeleport?: never
Expand Down Expand Up @@ -196,9 +196,9 @@ export interface MethodOptions {
}

export type ExtractComputedReturns<T extends any> = {
[key in keyof T]: T[key] extends { get: Function }
? ReturnType<T[key]['get']>
: ReturnType<T[key]>
[key in keyof T]: T[key] extends { get: (...args: any[]) => infer TReturn }
? TReturn
: T[key] extends (...args: any[]) => infer TReturn ? TReturn : never
}

type WatchOptionItem =
Expand Down
1 change: 1 addition & 0 deletions packages/runtime-core/src/components/Suspense.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ function createSuspenseBoundary(
/* istanbul ignore if */
if (__DEV__ && !__TEST__ && !hasWarned) {
hasWarned = true
// @ts-ignore `console.info` cannot be null error
console[console.info ? 'info' : 'log'](
`<Suspense> is an experimental feature and its API will likely change.`
)
Expand Down
1 change: 1 addition & 0 deletions packages/runtime-dom/types/jsx.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,7 @@ declare global {
}
interface IntrinsicElements extends NativeElements {
// allow arbitrary elements
// @ts-ignore supress ts:2374 = Duplicate string index signature.
[name: string]: any
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/vue/src/devCheck.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
if (__BROWSER__ && __DEV__) {
// @ts-ignore `console.info` cannot be null error
console[console.info ? 'info' : 'log'](
`You are running a development build of Vue.\n` +
`Make sure to use the production build (*.prod.js) when deploying for production.`
Expand Down
13 changes: 13 additions & 0 deletions test-dts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Test-ts

Tests Typescript types to ensure the types remain as expected.

## Configuration

### tsconfig.json

Config used to test against the package source

### tsconfig.build.json

Replaces the `vue` and `@vue/*` dependencies with the built Typescript to ensure the published types are correct.
5 changes: 3 additions & 2 deletions test-dts/componentTypeExtensions.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { expectError, expectType } from 'tsd'
import { defineComponent } from './index'
import { defineComponent, expectError, expectType } from './index'

declare module '@vue/runtime-core' {
interface ComponentCustomOptions {
Expand All @@ -20,9 +19,11 @@ export const Custom = defineComponent({

methods: {
aMethod() {
// @ts-expect-error
expectError(this.notExisting)
this.counter++
this.state = 'running'
// @ts-expect-error
expectError((this.state = 'not valid'))
}
}
Expand Down
31 changes: 23 additions & 8 deletions test-dts/defineComponent.test-d.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { expectError, expectType } from 'tsd'
import {
describe,
defineComponent,
PropType,
ref,
reactive,
createApp
createApp,
expectError,
expectType
} from './index'

describe('with object props', () => {
Expand Down Expand Up @@ -83,7 +84,7 @@ describe('with object props', () => {
expectType<ExpectedProps['eee']>(props.eee)
expectType<ExpectedProps['fff']>(props.fff)

// props should be readonly
// @ts-expect-error props should be readonly
expectError((props.a = 1))

// setup context
Expand Down Expand Up @@ -112,7 +113,7 @@ describe('with object props', () => {
expectType<ExpectedProps['eee']>(props.eee)
expectType<ExpectedProps['fff']>(props.fff)

// props should be readonly
// @ts-expect-error props should be readonly
expectError((props.a = 1))

// should also expose declared props on `this`
Expand All @@ -129,7 +130,7 @@ describe('with object props', () => {
expectType<ExpectedProps['eee']>(this.eee)
expectType<ExpectedProps['fff']>(this.fff)

// props on `this` should be readonly
// @ts-expect-error props on `this` should be readonly
expectError((this.a = 1))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is expectError necessery here? maybe it's enough to do

// @ts-expect-error props on `this` should be readonly
this.a = 1

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I kept the expectError to keep the same interface as before, felt a bit better to me, is not necessary to have it


// assert setup context unwrapping
Expand Down Expand Up @@ -167,13 +168,14 @@ describe('with object props', () => {
/>
)

// missing required props
// @ts-expect-error missing required props
expectError(<MyComponent />)

// wrong prop types
expectError(
// @ts-expect-error wrong prop types
<MyComponent a={'wrong type'} b="foo" dd={{ n: 1 }} ddd={['foo']} />
)
// @ts-expect-error
expectError(<MyComponent b="foo" dd={{ n: 'string' }} ddd={['foo']} />)
})

Expand Down Expand Up @@ -211,7 +213,7 @@ describe('type inference w/ array props declaration', () => {
defineComponent({
props: ['a', 'b'],
setup(props) {
// props should be readonly
// @ts-expect-error props should be readonly
expectError((props.a = 1))
expectType<any>(props.a)
expectType<any>(props.b)
Expand All @@ -222,6 +224,7 @@ describe('type inference w/ array props declaration', () => {
render() {
expectType<any>(this.$props.a)
expectType<any>(this.$props.b)
// @ts-expect-error
expectError((this.$props.a = 1))
expectType<any>(this.a)
expectType<any>(this.b)
Expand Down Expand Up @@ -340,19 +343,29 @@ describe('emits', () => {
setup(props, { emit }) {
emit('click', 1)
emit('input', 'foo')
// @ts-expect-error
expectError(emit('nope'))
// @ts-expect-error
expectError(emit('click'))
// @ts-expect-error
expectError(emit('click', 'foo'))
// @ts-expect-error
expectError(emit('input'))
// @ts-expect-error
expectError(emit('input', 1))
},
created() {
this.$emit('click', 1)
this.$emit('input', 'foo')
// @ts-expect-error
expectError(this.$emit('nope'))
// @ts-expect-error
expectError(this.$emit('click'))
// @ts-expect-error
expectError(this.$emit('click', 'foo'))
// @ts-expect-error
expectError(this.$emit('input'))
// @ts-expect-error
expectError(this.$emit('input', 1))
}
})
Expand All @@ -364,12 +377,14 @@ describe('emits', () => {
emit('foo')
emit('foo', 123)
emit('bar')
// @ts-expect-error
expectError(emit('nope'))
},
created() {
this.$emit('foo')
this.$emit('foo', 123)
this.$emit('bar')
// @ts-expect-error
expectError(this.$emit('nope'))
}
})
Expand Down
18 changes: 14 additions & 4 deletions test-dts/functionalComponent.test-d.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { expectError, expectType } from 'tsd'
import { FunctionalComponent } from './index'
import { FunctionalComponent, expectError, expectType } from './index'

// simple function signature
const Foo = (props: { foo: number }) => props.foo

// TSX
expectType<JSX.Element>(<Foo foo={1} />)
// expectError(<Foo />) // tsd does not catch missing type errors
// @ts-expect-error
expectError(<Foo />)
// @ts-expect-error
expectError(<Foo foo="bar" />)
// @ts-expect-error
expectError(<Foo baz="bar" />)

// Explicit signature with props + emits
Expand All @@ -18,24 +20,32 @@ const Bar: FunctionalComponent<
expectType<number>(props.foo)

emit('update', 123)
// @ts-expect-error
expectError(emit('nope'))
// @ts-expect-error
expectError(emit('update'))
// @ts-expect-error
expectError(emit('update', 'nope'))
}

// assigning runtime options
Bar.props = {
foo: Number
}
// @ts-expect-error
expectError((Bar.props = { foo: String }))

Bar.emits = {
update: value => value > 1
}
// @ts-expect-error
expectError((Bar.emits = { baz: () => void 0 }))

// TSX
expectType<JSX.Element>(<Bar foo={1} />)
// expectError(<Foo />) // tsd does not catch missing type errors
// @ts-expect-error
expectError(<Foo />)
// @ts-expect-error
expectError(<Bar foo="bar" />)
// @ts-expect-error
expectError(<Foo baz="bar" />)
34 changes: 26 additions & 8 deletions test-dts/h.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { expectError, expectAssignable } from 'tsd'
import {
describe,
h,
Expand All @@ -7,36 +6,48 @@ import {
Fragment,
Teleport,
Suspense,
Component
Component,
expectError,
expectAssignable
} from './index'

describe('h inference w/ element', () => {
// key
h('div', { key: 1 })
h('div', { key: 'foo' })
// @ts-expect-error
expectError(h('div', { key: [] }))
// @ts-expect-error
expectError(h('div', { key: {} }))
// ref
h('div', { ref: 'foo' })
h('div', { ref: ref(null) })
h('div', { ref: el => {} })
// @ts-expect-error
expectError(h('div', { ref: [] }))
// @ts-expect-error
expectError(h('div', { ref: {} }))
// @ts-expect-error
expectError(h('div', { ref: 123 }))
})

describe('h inference w/ Fragment', () => {
// only accepts array children
h(Fragment, ['hello'])
h(Fragment, { key: 123 }, ['hello'])
// @ts-expect-error
expectError(h(Fragment, 'foo'))
// @ts-expect-error
expectError(h(Fragment, { key: 123 }, 'bar'))
})

describe('h inference w/ Teleport', () => {
h(Teleport, { to: '#foo' }, 'hello')
// @ts-expect-error
expectError(h(Teleport))
// @ts-expect-error
expectError(h(Teleport, {}))
// @ts-expect-error
expectError(h(Teleport, { to: '#foo' }))
})

Expand All @@ -47,15 +58,19 @@ describe('h inference w/ Suspense', () => {
h(Suspense, null, {
default: () => 'foo'
})
// @ts-expect-error
expectError(h(Suspense, { onResolve: 1 }))
})

describe('h inference w/ functional component', () => {
const Func = (_props: { foo: string; bar?: number }) => ''
h(Func, { foo: 'hello' })
h(Func, { foo: 'hello', bar: 123 })
// @ts-expect-error
expectError(h(Func, { foo: 123 }))
// @ts-expect-error
expectError(h(Func, {}))
// @ts-expect-error
expectError(h(Func, { bar: 123 }))
})

Expand Down Expand Up @@ -85,10 +100,11 @@ describe('h inference w/ defineComponent', () => {
h(Foo, { bar: 1, foo: 'ok' })
// should allow extraneous props (attrs fallthrough)
h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
// should fail on missing required prop
// @ts-expect-error should fail on missing required prop
expectError(h(Foo, {}))
// @ts-expect-error
expectError(h(Foo, { foo: 'ok' }))
// should fail on wrong type
// @ts-expect-error should fail on wrong type
expectError(h(Foo, { bar: 1, foo: 1 }))
})

Expand All @@ -101,10 +117,11 @@ describe('h inference w/ defineComponent + optional props', () => {
h(Foo, { bar: 1, foo: 'ok' })
// should allow extraneous props (attrs fallthrough)
h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
// should fail on missing required prop
// @ts-expect-error should fail on missing required prop
expectError(h(Foo, {}))
// @ts-expect-error
expectError(h(Foo, { foo: 'ok' }))
// should fail on wrong type
// @ts-expect-error should fail on wrong type
expectError(h(Foo, { bar: 1, foo: 1 }))
})

Expand All @@ -115,10 +132,11 @@ describe('h inference w/ defineComponent + direct function', () => {
h(Foo, { bar: 1, foo: 'ok' })
// should allow extraneous props (attrs fallthrough)
h(Foo, { bar: 1, foo: 'ok', class: 'extra' })
// should fail on missing required prop
// @ts-expect-error should fail on missing required prop
expectError(h(Foo, {}))
// @ts-expect-error
expectError(h(Foo, { foo: 'ok' }))
// should fail on wrong type
// @ts-expect-error should fail on wrong type
expectError(h(Foo, { bar: 1, foo: 1 }))
})

Expand Down
4 changes: 4 additions & 0 deletions test-dts/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,7 @@
export * from '@vue/runtime-dom'

export function describe(_name: string, _fn: () => void): void

export function expectType<T>(value: T): void
export function expectError<T>(value: T): void
export function expectAssignable<T, T2 extends T = T>(value: T2): void
Loading