Skip to content

Commit 75c8cf6

Browse files
authored
feat(types): provide internal options for directly using user types in language tools (#10801)
1 parent 4cc9ca8 commit 75c8cf6

File tree

10 files changed

+652
-475
lines changed

10 files changed

+652
-475
lines changed

Diff for: packages/dts-test/defineComponent.test-d.tsx

+144-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
withKeys,
1616
withModifiers,
1717
} from 'vue'
18-
import { type IsUnion, describe, expectType } from './utils'
18+
import { type IsAny, type IsUnion, describe, expectType } from './utils'
1919

2020
describe('with object props', () => {
2121
interface ExpectedProps {
@@ -1623,3 +1623,146 @@ declare const MyButton: DefineComponent<
16231623
{}
16241624
>
16251625
;<MyButton class="x" />
1626+
1627+
describe('__typeProps backdoor for union type for conditional props', () => {
1628+
interface CommonProps {
1629+
size?: 'xl' | 'l' | 'm' | 's' | 'xs'
1630+
}
1631+
1632+
type ConditionalProps =
1633+
| {
1634+
color?: 'normal' | 'primary' | 'secondary'
1635+
appearance?: 'normal' | 'outline' | 'text'
1636+
}
1637+
| {
1638+
color: 'white'
1639+
appearance: 'outline'
1640+
}
1641+
1642+
type Props = CommonProps & ConditionalProps
1643+
1644+
const Comp = defineComponent({
1645+
__typeProps: {} as Props,
1646+
})
1647+
// @ts-expect-error
1648+
;<Comp color="white" />
1649+
// @ts-expect-error
1650+
;<Comp color="white" appearance="normal" />
1651+
;<Comp color="white" appearance="outline" />
1652+
1653+
const c = new Comp()
1654+
1655+
// @ts-expect-error
1656+
c.$props = { color: 'white' }
1657+
// @ts-expect-error
1658+
c.$props = { color: 'white', appearance: 'text' }
1659+
c.$props = { color: 'white', appearance: 'outline' }
1660+
})
1661+
1662+
describe('__typeEmits backdoor, 3.3+ object syntax', () => {
1663+
type Emits = {
1664+
change: [id: number]
1665+
update: [value: string]
1666+
}
1667+
1668+
const Comp = defineComponent({
1669+
__typeEmits: {} as Emits,
1670+
mounted() {
1671+
this.$props.onChange?.(123)
1672+
// @ts-expect-error
1673+
this.$props.onChange?.('123')
1674+
this.$props.onUpdate?.('foo')
1675+
// @ts-expect-error
1676+
this.$props.onUpdate?.(123)
1677+
1678+
// @ts-expect-error
1679+
this.$emit('foo')
1680+
1681+
this.$emit('change', 123)
1682+
// @ts-expect-error
1683+
this.$emit('change', '123')
1684+
1685+
this.$emit('update', 'test')
1686+
// @ts-expect-error
1687+
this.$emit('update', 123)
1688+
},
1689+
})
1690+
1691+
;<Comp onChange={id => id.toFixed(2)} />
1692+
;<Comp onUpdate={id => id.toUpperCase()} />
1693+
// @ts-expect-error
1694+
;<Comp onChange={id => id.slice(1)} />
1695+
// @ts-expect-error
1696+
;<Comp onUpdate={id => id.toFixed(2)} />
1697+
1698+
const c = new Comp()
1699+
// @ts-expect-error
1700+
c.$emit('foo')
1701+
1702+
c.$emit('change', 123)
1703+
// @ts-expect-error
1704+
c.$emit('change', '123')
1705+
1706+
c.$emit('update', 'test')
1707+
// @ts-expect-error
1708+
c.$emit('update', 123)
1709+
})
1710+
1711+
describe('__typeEmits backdoor, call signature syntax', () => {
1712+
type Emits = {
1713+
(e: 'change', id: number): void
1714+
(e: 'update', value: string): void
1715+
}
1716+
1717+
const Comp = defineComponent({
1718+
__typeEmits: {} as Emits,
1719+
mounted() {
1720+
this.$props.onChange?.(123)
1721+
// @ts-expect-error
1722+
this.$props.onChange?.('123')
1723+
this.$props.onUpdate?.('foo')
1724+
// @ts-expect-error
1725+
this.$props.onUpdate?.(123)
1726+
1727+
// @ts-expect-error
1728+
this.$emit('foo')
1729+
1730+
this.$emit('change', 123)
1731+
// @ts-expect-error
1732+
this.$emit('change', '123')
1733+
1734+
this.$emit('update', 'test')
1735+
// @ts-expect-error
1736+
this.$emit('update', 123)
1737+
},
1738+
})
1739+
1740+
;<Comp onChange={id => id.toFixed(2)} />
1741+
;<Comp onUpdate={id => id.toUpperCase()} />
1742+
// @ts-expect-error
1743+
;<Comp onChange={id => id.slice(1)} />
1744+
// @ts-expect-error
1745+
;<Comp onUpdate={id => id.toFixed(2)} />
1746+
1747+
const c = new Comp()
1748+
// @ts-expect-error
1749+
c.$emit('foo')
1750+
1751+
c.$emit('change', 123)
1752+
// @ts-expect-error
1753+
c.$emit('change', '123')
1754+
1755+
c.$emit('update', 'test')
1756+
// @ts-expect-error
1757+
c.$emit('update', 123)
1758+
})
1759+
1760+
defineComponent({
1761+
props: {
1762+
foo: [String, null],
1763+
},
1764+
setup(props) {
1765+
expectType<IsAny<typeof props.foo>>(false)
1766+
expectType<string | null | undefined>(props.foo)
1767+
},
1768+
})

0 commit comments

Comments
 (0)