在一些情况下(如小项目等),我更喜欢用 Javascript ,同时也不介意使用 Typescript, 特别在一些较大的项目,特别是在使用 Svelte 进行表单验证的时候。
在使用 Svelte 不涉及表单验证等复杂场景的时候,
直接使用 Javascript 和 JSDoc
也可以获得不错的类型提示体验也很方便。
但在更复杂的场景如使用Superforms 和 Zod 进行表单验证的时候,
Typescript 会有更友好的编码体验(类型提示和类型检查)。
JsDoc类型注释
类型注释和使用可以在同一个文件,如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/**
* @typedef Invoice
* @type {Object}
* @property {string} invoice
* @property {string} paymentStatus
* @property {string} totalAmount
* @property {string} paymentMethod - payment method
*/
/** @type {Array<Invoice>} */
export const invoices = [
{
invoice: "INV001",
paymentStatus: "Paid",
totalAmount: "$250.00",
paymentMethod: "Credit Card"
}
]
|
也可以在跨文件共享使用类型注释:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// file: types.js
/**
* @typedef Invoice
* @type {Object}
* @property {string} invoice
* @property {string} paymentStatus
* @property {string} totalAmount
* @property {string} paymentMethod - payment method
*/
// file: invoice.js
/** @type { import('./types.js').Invoice[] } */
export const invoices = [
{
invoice: "INV001",
paymentStatus: "Paid",
totalAmount: "$250.00",
paymentMethod: "Credit Card",
},
];
|
Svelte 使用 TypeScript
在 Svelte components、Props、Slots、Events、Bindings 时,使用 Typescript 只需要将 lang="ts
添加到 script
标签:
1
2
3
4
5
6
7
|
<script lang="ts">
let name: string = 'world';
function greet(name: string) {
alert(`Hello, ${name}!`);
}
</script>
|
1
2
3
|
<script lang="ts">
export let name: string;
</script>
|
1
2
3
4
5
6
7
8
9
10
11
|
<script lang="ts">
export let name: string;
</script>
<slot {name} />
<!-- Later -->
<Comp let:name>
<!-- ^ Inferred as string -->
{name}
</Comp>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<script lang="ts">
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher<{
event: null; // does not accept a payload
click: string; // has a required string payload
type: string | null; // has an optional string payload
}>();
function handleClick() {
dispatch('event');
dispatch('click', 'hello');
}
function handleType() {
dispatch('event');
dispatch('type', Math.random() > 0.5 ? 'world' : null);
}
</script>
<button on:click={handleClick} on:keydown={handleType}>Click</button>
|
Svelte 和 Zod
使用 zod validation library 时使用 Typescript 会更方便:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
const accountSchema = z.object({
name: z
.string({ required_error: 'Required.' })
.min(2, 'Name must be at least 2 characters.')
.max(30, 'Name must not be longer than 30 characters.'),
language: z.enum(languages.map(lang => lang.value) as [Language, ...Language[]]),
dob: z
.string()
.datetime()
.optional()
.refine((date) => (date === undefined ? false : true), 'Please select a valid date.')
});
type AccountSchema = typeof accountSchema
|
此时如果不是在.ts
文件使用zod, 而是有JSDoc注释 的常规.js
文件,可以使用下面的方式,在JSDoc 中推断Zod类型:
1
2
3
4
5
6
7
8
9
10
11
|
export const _formSchema = z.object({
username: z.string().min(2, '最少两个字符').max(50, '最多50个字符'),
email: z.string().email('无效邮箱地址'),
bio: z.string().min(4).max(160).default("I own a computer."),
urls: z
.array(z.string().url())
.default(["https://shadcn.com", "https://twitter.com/shadcn"]),
})
// Extract the inferred type as a JSDoc type
/** @typedef { z.infer<typeof _formSchema>} _form */
|
参考