Last active
March 3, 2025 10:12
-
-
Save Kcko/1f7afa4ef1cdf83a284248656decacd2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- 1. PROPS --> | |
<!-- JS --> | |
<script setup> | |
import { defineProps } from 'vue'; | |
const props = defineProps({ | |
foo: { type: String, required: true }, | |
bar: Number, | |
}); | |
// props.foo is a string | |
// props.bar is a number or undefined | |
</script> | |
<!-- TS --> | |
<script setup lang="ts"> | |
const props = defineProps<{ | |
foo: string; | |
bar?: number; | |
}>() | |
</script> | |
<script setup lang="ts"> | |
interface Props { | |
foo: string; | |
bar?: number; | |
} | |
const props = defineProps<Props>() | |
</script> | |
<!-- 2. EMITS --> | |
<!-- JS --> | |
<script setup> | |
const emit = defineEmits(['change', 'update']) | |
</script> | |
<!-- TS --> | |
<script setup lang="ts"> | |
const emit = defineEmits<{ | |
change: [id: number] | |
update: [value: string] | |
}>() | |
</script> | |
<!-- 3. Typing Ref and Reactive Data => Inference --> | |
<script setup> | |
import { ref } from 'vue'; | |
const count = ref(0); | |
count.value = 'string'; // error, inference, we expect number | |
</script> | |
<!-- 4. Typing Server Responses --> | |
<script setup lang="ts"> | |
import { ref, onMounted } from 'vue'; | |
interface User { | |
id: number; | |
name: string; | |
email: string; | |
} | |
const userData = ref<User | null>(null); | |
onMounted(async () => { | |
const response = await fetch('https://api.example.com/user'); | |
const data: User = await response.json(); | |
userData.value = data; // TypeScript ensures data usages match the User interface | |
}); | |
</script> | |
<!-- 5. Typing Computed Data --> | |
import { ref, computed } from 'vue' | |
const count = ref(0) | |
// inferred type: ComputedRef<number> | |
const double = computed(() => count.value * 2) | |
// => TS Error: Property 'split' does not exist on type 'number' | |
const result = double.value.split('') | |
// or explicitely define return type | |
const double = computed<number>(() => { | |
// type error if this doesn't return a number | |
}) | |
<!-- 6. Typing Scoped Slots--> | |
<template> | |
<slot :msg="message"></slot> | |
</template> | |
<script setup lang="ts"> | |
const message = 'Hello, Vue!'; | |
const slots = defineSlots<{ | |
default: (props: { msg: string }) => any; | |
}>() | |
</script> | |
<!-- 7. Typing Template Refs --> | |
<script setup lang="ts"> | |
import { useTemplateRef, onMounted } from 'vue'; | |
const myInput = useTemplateRef('my-input'); | |
onMounted(() => { | |
myInput.value?.focus(); | |
}); | |
</script> | |
<template> | |
<input ref="my-input" /> | |
</template> | |
<!-- 8. Typing Provide/Inject --> | |
<!-- ParentComponent.vue --> | |
<script setup lang="ts"> | |
import { provide } from 'vue'; | |
const theme = 'dark'; | |
provide('theme', theme); | |
</script> | |
<!-- ChildComponent.vue --> | |
<script setup lang="ts"> | |
import { inject } from 'vue'; | |
const theme = inject<string>('theme'); // Inject with expected type | |
// TypeScript ensures that 'theme' is of type string | |
</script> | |
<!-- 9. Generics --> | |
<script setup lang="ts" generic="T"> | |
defineProps<{ | |
items: T[]; // Array of items of type T | |
selected: T; // Single selected item of type T | |
}>() | |
</script> | |
<!-- 10. Typed Composables --> | |
// useUser.ts | |
import { ref } from 'vue'; | |
interface User { | |
id: number; | |
name: string; | |
age: number; | |
} | |
export function useUser() { | |
const user = ref<User | null>(null); | |
function fetchUser(id: number) { | |
// Fetching user logic | |
user.value = { id, name: 'John Doe', age: 30 }; | |
} | |
return { user, fetchUser }; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment