1. 泛型(Generics)
泛型(Generics)是 TypeScript 中的一种功能,允许你在声明时不指定具体的类型,而是在使用时指定具体类型,从而提高代码的复用性和灵活性。
示例:泛型函数
function identity<T>(arg: T): T {
return arg;
}
const result = identity(42); // T 被推导为 number
const result2 = identity("hello"); // T 被推导为 string
identity<T>
是一个泛型函数,T
代表一个类型参数,表示函数接受的参数类型和返回值类型都是T
。- 在调用时,TypeScript 会根据传入的参数自动推导
T
的具体类型。
示例:泛型接口
interface Box<T> {
value: T;
}
const numberBox: Box<number> = { value: 42 };
const stringBox: Box<string> = { value: "hello" };
Box<T>
是一个泛型接口,表示value
属性的类型是T
,可以在实例化时指定具体类型。
示例:泛型类
class Container<T> {
private items: T[] = [];
addItem(item: T): void {
this.items.push(item);
}
getItems(): T[] {
return this.items;
}
}
const numberContainer = new Container<number>();
numberContainer.addItem(1);
console.log(numberContainer.getItems()); // 输出: [1]
const stringContainer = new Container<string>();
stringContainer.addItem("hello");
console.log(stringContainer.getItems()); // 输出: ["hello"]
Container<T>
是一个泛型类,允许我们在创建实例时指定元素类型。
2. 箭头函数中的泛型
在箭头函数中使用泛型可以提供灵活的类型推导,尤其是函数签名复杂时,使用泛型让函数更具通用性。
示例:箭头函数中的泛型
const add = <T extends number | string>(a: T, b: T): T => {
return (a + b) as T;
};
const sum = add(5, 10); // T 被推导为 number
const concat = add("Hello, ", "World!"); // T 被推导为 string
- 在箭头函数中,
<T extends number | string>
限制了T
只能是number
或string
类型,确保了泛型的类型安全。 - 该函数可以接受
number
类型或string
类型的两个参数,并返回相同类型的结果。
示例:复杂函数签名中的泛型
type ApiRequest<F, T> = (
formData: F,
page: { current: number; pageSize: number }
) => Promise<{ total: number; list: T[] }>;
const request: ApiRequest<{ searchTerm: string }, { id: number; name: string }> = async (formData, page) => {
const data = await fetchData(formData, page);
return {
total: data.total,
list: data.items,
};
};
ApiRequest<F, T>
是一个泛型类型,F
是表单数据类型,T
是返回数据类型。通过泛型来定义请求函数的参数和返回值类型。- 在
request
实例中,formData
被指定为{ searchTerm: string }
,T
被指定为{ id: number; name: string }
。
3. 类型断言(Type Assertion)
类型断言用于告诉 TypeScript 编译器一个值的类型,即使编译器无法推导出类型。这可以用来确保在某些情况下类型是正确的。
示例:类型断言
let someValue: any = "Hello, TypeScript!";
let strLength: number = (<string>someValue).length; // 断言为 string 类型
console.log(strLength); // 输出: 18
<string>
是类型断言,表示someValue
是一个string
类型,尽管其类型是any
。
示例:使用 as
语法进行类型断言
let someValue: any = { id: 1, name: "Item" };
let itemName: string = (someValue as { name: string }).name;
console.log(itemName); // 输出: "Item"
- 使用
as
语法进行类型断言,告诉 TypeScriptsomeValue
应该被视为{ name: string }
类型。
注意:
- 在 React 中,类型断言常用于事件处理或 DOM 元素操作,避免类型推导错误。
4. React Props 类型声明(泛型)
在 React 中,我们可以使用 泛型 来声明组件的 Props 类型,使得组件更加灵活和类型安全。
示例:React 组件的泛型 Props
interface MyComponentProps<T> {
value: T;
}
const MyComponent = <T,>({ value }: MyComponentProps<T>) => {
return <div>{value}</div>;
};
const App = () => {
return (
<>
<MyComponent value={42} />
<MyComponent value={"Hello"} />
</>
);
};
MyComponent
是一个泛型组件,<T,>
使组件接受任意类型的value
属性。- 当使用
MyComponent
时,value
的类型可以是number
或string
,根据传入的值自动推导。
示例:带默认类型的泛型 Props
interface MyComponentProps<T = number> {
value: T;
}
const MyComponent = <T,>({ value }: MyComponentProps<T>) => {
return <div>{value}</div>;
};
const App = () => {
return (
<>
<MyComponent value={42} />
<MyComponent value={"Hello"} />
</>
);
};
MyComponentProps<T = number>
为T
提供了默认类型number
,但你依然可以在实例化组件时指定不同的类型。
5. 数组类型声明
在 TypeScript 中,使用尖括号来声明数组的元素类型。
示例:数组类型声明
let numbers: Array<number> = [1, 2, 3, 4];
let strings: string[] = ["a", "b", "c"];
Array<number>
和string[]
是等价的,表示声明一个数组,该数组的每个元素都属于number
或string
类型。
示例:泛型与数组类型结合
function getArray<T>(items: T[]): T[] {
return new Array().concat(items);
}
const numArray = getArray([1, 2, 3]); // numArray 类型是 number[]
const strArray = getArray(["a", "b", "c"]); // strArray 类型是 string[]
getArray<T>
是一个泛型函数,它接受一个数组并返回相同类型的数组。
总结
- 泛型(Generics):提高函数、类、接口的复用性和灵活性,允许函数、类或接口在声明时不指定类型,在使用时指定类型。
- 箭头函数中的泛型:在箭头函数中使用泛型,使得函数签名灵活,尤其在函数逻辑复杂时,能够根据具体类型进行操作。
- 类型断言(Type Assertion):用于告诉 TypeScript 编译器某个值的类型,用于修正编译器推导的类型,尤其是在某些类型无法直接推导时。
- React Props 类型声明(泛型):在 React 中使用泛型声明组件的 Props 类型,使组件能够接受不同类型的 props,从而提高组件的灵活性。
- 数组类型声明:使用尖括号声明数组的元素类型,使得数组的每个元素类型一致。
这些技术可以大大提高代码的类型安全性、可读性和可维护性,尤其在大型项目中,泛型的使用使得开发更加灵活、强大。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容