Typing Composables and Refs
Ref , ComputedRef , typed return from composables, MaybeRef .
Typing Composables and Refs is a free Vue Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Vue Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Typing the Composition API
Composables are just functions, and refs are just typed containers. Adding explicit types makes your composables safe to consume and gives callers full autocomplete.
Inferred ref Types
Most of the time TypeScript infers a ref type from its initial value. A ref(0) is a Ref<number> automatically.
import { ref } from 'vue'
const count = ref(0) // Ref<number>
const name = ref('Coddy') // Ref<string>Explicit ref Generics
When the initial value cannot express the full type — like a value that starts null but becomes an object — pass an explicit generic.
interface User { id: number; name: string }
const user = ref<User | null>(null)The Ref Type
Ref<T> describes a writable ref whose .value is of type T. Use it to annotate variables or function parameters that receive refs.
import type { Ref } from 'vue'
function useDouble(n: Ref<number>) {
return computed(() => n.value * 2)
}The ComputedRef Type
A computed returns a read-only ComputedRef<T>. Use this type when annotating a composable that returns computed values.
import type { ComputedRef } from 'vue'
const doubled: ComputedRef<number> = computed(() => count.value * 2)Typing a Composable Return
Annotate the return shape so consumers see exactly what they get. An explicit return type also documents the composable.
import { ref, type Ref } from 'vue'
function useCounter(): { count: Ref<number>; increment: () => void } {
const count = ref(0)
const increment = () => count.value++
return { count, increment }
}Letting Inference Work
Often you can omit the explicit return type and let TypeScript infer it. Add an explicit type only when you want a stable public contract.
MaybeRef for Flexible Inputs
MaybeRef<T> means a value that may be a plain T or a Ref<T>. It lets composables accept either form.
import type { MaybeRef } from 'vue'
function useGreeting(name: MaybeRef<string>) {
// name could be 'Coddy' or ref('Coddy')
}Unwrapping With unref
unref(x) returns x.value if x is a ref, otherwise x itself. Pair it with MaybeRef to normalize the input.
import { unref, type MaybeRef } from 'vue'
function useGreeting(name: MaybeRef<string>) {
const text = unref(name) // always a string
return 'Hello ' + text
}toValue: The Modern Helper
Vue 3.3 added toValue, which unwraps refs and calls getter functions. It is the preferred way to normalize MaybeRefOrGetter inputs.
import { toValue, type MaybeRefOrGetter } from 'vue'
function useLen(input: MaybeRefOrGetter<string>) {
return computed(() => toValue(input).length)
}Typing Reactive Objects
reactive infers the object type directly — no .value needed. For explicit typing, annotate the variable with the object interface.
import { reactive } from 'vue'
interface State { count: number; name: string }
const state: State = reactive({ count: 0, name: '' })Quick Check
Test your knowledge of typing composables and refs.
Recap
You learned to type the Composition API:
- ref infers types; use ref<T>() when the initial value is insufficient.
- Ref<T> and ComputedRef<T> annotate refs and computeds.
- Type composable returns for a clear contract.
- MaybeRef<T> + unref()/toValue() accept flexible inputs.
Frequently asked questions
Is the “Typing Composables and Refs” lesson free?
Yes — the full text of “Typing Composables and Refs” is free to read here on the web, and the Vue Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Vue Academy course, upgrade to CoddyKit PRO.
What will I learn in “Typing Composables and Refs”?
Ref , ComputedRef , typed return from composables, MaybeRef . You practise Vue Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Vue Academy?
No prior experience is required. Vue Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Typing Composables and Refs” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Vue Academy lesson?
Yes. Every Vue Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- TypeScript Setup in Vue Projects
- Typed Props and Emits with defineProps/defineEmits
- Typing Composables and Refs
- Generic Vue Components