一个函数的参数是vue的ref类型,该如何进行ts声明呢?
一个变量inputEl
是ref<HTMLInputElement>
类型,将其传给了函数useCursor
:
// App.vue
import useCursor from './useCursor';
const inputEl = ref<HTMLInputElement | undefined>();
useCursor(inputEl)
在useCursor
中对inputEl
的类型定义:
// useCursor.ts
type InputElementRef = Ref<HTMLInputElement | undefined>;
function useCursor(inputEl: InputElementRef) {
// ...
}
优化一下,将类型定义共享:
// types.ts
export type InputElementRef = HTMLInputElement | undefined;
// App.vue
import { InputElementRef } from './types.ts';
import useCursor from './useCursor';
const inputEl = ref<InputElementRef>();
useCursor(inputEl)
// useCursor.ts
import { InputElementRef } from './types.ts';
function useCursor(inputEl: InputElementRef) {
// ...
}
react的键盘事件对象如何定义类型?
type ReactKeyboardEvent = React.KeyboardEvent<HTMLInputElement>;
const onKeyDown = (e: ReactKeyboardEvent) => {
// ...
};
<input onKeyDown={onKeyDown} />
ReactNode、ReactElement、ReactChild、ReactText、 ReactElement
type ReactText = string | number;
type ReactChild = ReactElement | ReactText;
type ReactNode = ReactChild | boolean | null | undefined;
ReactNode
当你希望一个函数或组件接受任何类型的React
子节点时,你应该使用ReactNode
。
例如:children
,就适合用ReactNode
。
ReactElement
ReactElement
是React.createElement()
的返回值。
通常包含type
(组件或DOM
标签名)、props
和可选的key
属性。
当值为一个jsx内容时,你应该用ReactElement
例如:
const Demo = (): ReactElement => <div>Hello</div>
const div: ReactElement = <div />
资料:
when-to-use-jsx-element-vs-reactnode-vs-reactelement
Cannot find name 'defineProps'.Vetur(2304)
可能的原因之一是你启用了vscode
的Vetur
插件,该插件对Vue3
的支持不足导致。
在Vue3
中,Vetur
和TypeScript Vue Plugin (Volar)
已经被Vue - Official
取代了,所以,确保禁用或者卸载掉前面两个插件,安装Vue - Official
。
拓展一个类型
在ModalProps
的基础上添加了一个isFullscreen
属性。
import { Modal } from 'antd';
type ModalProps = React.ComponentProps<typeof Modal>
type ModalPropsWithFullscreen = ModalProps & { isFullscreen: boolean };
场景:
在antd
的组件基础上进行二次封装。
下面就是对antd
的Modal
组件进行二次封装,然后在默认props
上添加了自定义的prop
。
const ModalEnhanced: FC<ModalPropsWithFullscreen> = (props) => {
const { children } = props;
return (
<div>
<Modal {...props}>
{children}
</Modal>
</div>
);
};
定义interface
定义一个interface
类型,拥有基础的name、age、gender
属性,并且可以自由扩展额外的属性。
下面两种定义方式是等价的,可以根据自己的喜好选择。
// 方式1 扩展性更好
type Person = {
name: string;
age: num;
gender: string;
} & Record<string, any>;
// 方式2 代码更清晰
interface Person {
code: string;
age: num;
gender: string;
[key: string]: any;
}
断言
// 断言document.getElementById('btn')的返回值是一个HTMLElement元素
const btn = document.getElementById('btn') as HTMLElement;
DOM元素类型定义
const btn = document.getElementById('btn');
// Property 'style' does not exist on type 'Element'.ts(2339)
btn.style.display = 'none';
需要对btn
进行类型声明
// 1 在声明变量时指定类型
const btn: HTMLElement = document.getElementById('btn');
btn.style.display = 'none';
// 2 使用as关键字进行类型断言
const btn = document.getElementById('btn') as HTMLElement;
btn.style.display = 'none';
两种方式都可以,但是第一种方式更推荐,因为第一种方式在编译阶段就会检查,而第二种是在运行时检查。
Record
Record用来定义对象的键和值的类型,也就是key
和value
。
// 下面用Record定义了一个对象,键string类型,值为any类型。
type query = Record<string, any>;
const params: query = {
name: 'Duo',
age: 10,
desc: undefined,
children: [],
target: null,
}
枚举
type Page = "home" | "about" | "contact";
// pageName为Page枚举类型,其值只能为home\about\contact三者其一。
const pageName: Page = 'home';
枚举也可以与Record
组合使用
type Page = "home" | "about" | "contact";
// 此时,pages的key只能为home\about\contact三者其一。
const pages : Record<Page, string> = {
home: '首页',
}
定义React组件
函数声明
interface TitleProps {
name: string;
}
function Title({ name }: TitleProps) {
return (
<div className="container">
{name}
</div>
);
}
函数表达式
import React from 'react';
interface TitleProps {
name: string;
}
const Title: React.FC<TitleProps> = ({ name }) => (
<div className="container">
{name}
</div>
);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。