ref.test-d.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import { Ref, ref, isRef, unref, reactive, expectType } from './index'
  2. function plainType(arg: number | Ref<number>) {
  3. // ref coercing
  4. const coerced = ref(arg)
  5. expectType<Ref<number>>(coerced)
  6. // isRef as type guard
  7. if (isRef(arg)) {
  8. expectType<Ref<number>>(arg)
  9. }
  10. // ref unwrapping
  11. expectType<number>(unref(arg))
  12. // ref inner type should be unwrapped
  13. const nestedRef = ref({
  14. foo: ref(1)
  15. })
  16. expectType<Ref<{ foo: number }>>(nestedRef)
  17. expectType<{ foo: number }>(nestedRef.value)
  18. // ref boolean
  19. const falseRef = ref(false)
  20. expectType<Ref<boolean>>(falseRef)
  21. expectType<boolean>(falseRef.value)
  22. // ref true
  23. const trueRef = ref<true>(true)
  24. expectType<Ref<true>>(trueRef)
  25. expectType<true>(trueRef.value)
  26. // tuple
  27. expectType<[number, string]>(unref(ref([1, '1'])))
  28. interface IteratorFoo {
  29. [Symbol.iterator]: any
  30. }
  31. // with symbol
  32. expectType<Ref<IteratorFoo | null | undefined>>(
  33. ref<IteratorFoo | null | undefined>()
  34. )
  35. // should not unwrap ref inside arrays
  36. const arr = ref([1, new Map<string, any>(), ref('1')]).value
  37. const value = arr[0]
  38. if (isRef(value)) {
  39. expectType<Ref>(value)
  40. } else if (typeof value === 'number') {
  41. expectType<number>(value)
  42. } else {
  43. // should narrow down to Map type
  44. // and not contain any Ref type
  45. expectType<Map<string, any>>(value)
  46. }
  47. // should still unwrap in objects nested in arrays
  48. const arr2 = ref([{ a: ref(1) }]).value
  49. expectType<number>(arr2[0].a)
  50. }
  51. plainType(1)
  52. function bailType(arg: HTMLElement | Ref<HTMLElement>) {
  53. // ref coercing
  54. const coerced = ref(arg)
  55. expectType<Ref<HTMLElement>>(coerced)
  56. // isRef as type guard
  57. if (isRef(arg)) {
  58. expectType<Ref<HTMLElement>>(arg)
  59. }
  60. // ref unwrapping
  61. expectType<HTMLElement>(unref(arg))
  62. // ref inner type should be unwrapped
  63. // eslint-disable-next-line no-restricted-globals
  64. const nestedRef = ref({ foo: ref(document.createElement('DIV')) })
  65. expectType<Ref<{ foo: HTMLElement }>>(nestedRef)
  66. expectType<{ foo: HTMLElement }>(nestedRef.value)
  67. }
  68. // eslint-disable-next-line no-restricted-globals
  69. const el = document.createElement('DIV')
  70. bailType(el)
  71. function withSymbol() {
  72. const customSymbol = Symbol()
  73. const obj = {
  74. [Symbol.asyncIterator]: { a: 1 },
  75. [Symbol.unscopables]: { b: '1' },
  76. [customSymbol]: { c: [1, 2, 3] }
  77. }
  78. const objRef = ref(obj)
  79. expectType<{ a: number }>(objRef.value[Symbol.asyncIterator])
  80. expectType<{ b: string }>(objRef.value[Symbol.unscopables])
  81. expectType<{ c: Array<number> }>(objRef.value[customSymbol])
  82. }
  83. withSymbol()
  84. const state = reactive({
  85. foo: {
  86. value: 1,
  87. label: 'bar'
  88. }
  89. })
  90. expectType<string>(state.foo.label)