指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性。
下面创建一个函数, 实现功能: 根据指定的数量 count 和数据 value , 创建一个包含 count 个 value 的数组 不用泛型的话,这个函数可能是下面这样:
function createArray(value: any, count: number): any[] {
const arr: any[] = []
for (let index=0; index < count; index++) {
arr.push(value)
}
return arr
}
const arr1 = createArray('a', 3)
const arr2 = createArray(1, 3)
console.log(arr1)
console.log(arr2)
console.log(arr1[0].toFixed(), arr2[0].split(''))
我们创建了一个函数createArray,传入2个参数value和count,返回any类型的数组,然后定义了一个any类型的空数组arr。接下来我们查看结果

在编译阶段我们没有报错是因为,我们把value设置为了any类型,但是当编译完成后运行时,arr1是字符串,字符串是没有toFixed方法的,所以会报错,那么我们希望在编译阶段就报错,就可以使用泛型
// 使用函数泛型
function createArray<T>(value: T, count: number): T[] {
const arr: Array<T> = []
for (let index=0; index < count; index++) {
arr.push(value)
}
return arr
}
const arr1 = createArray<number>(11, 3)
console.log(arr1[0].toFixed())
const arr2 = createArray<string>('AA', 3)
console.log(arr2[0].split(''))
console.log('---------')
console.log(arr2[0].toFixed()) // 报错,因为字符串没有toFixed方法
console.log(arr1[0].split('')) // 报错,因为number没有split方法
泛型的意思就是类型由用户自己决定,比如function createArray<T>(value: T, count: number): T[],函数createArray和value参数和返回类型都由用户自己决定。
const arr1 = createArray<number>(11, 3)这句代码是没问题,因为规定了number类型,传入的也是number
当我们将代码修改成如下代码:

我们发现报错了,因为规定了number类型,传入的却是字符串11,

当我们输入如下代码,也会报错

报错原因如下

所以如果我们使用了泛型,就会避免类型输入错误或者用错方法
一个函数可以定义多个泛型参数
function swap <K, V> (a: K, b: V): [K, V] {
return [a, b]
}
const result = swap<string, number>('abc', 123)
console.log(result[0].length, result[1].toFixed())
interface IbaseCRUD <T> {
// 定义泛型数组data
data: T[]
add: (t: T) => void
getById: (id: number) => T
}
class User {
id?: number;
name: string;
age: number;
constructor(name, age) {
this.name = name;
this.age = age;
}
}
class UserCRUD implements IbaseCRUD<User> {
data: User[] = []
add(user: User): void {
user = {...user, id: Date.now()}
this.data.push(user)
console.log('保存user', user.id)
}
getById(id: number): User {
return this.data.find(item => item.id === id)
}
}
const userCRUD = new UserCRUD()
userCRUD.add(new User('tom', 12))
userCRUD.add(new User('tom2', 13))
console.log(userCRUD.data)
泛型类看上去与泛型接口差不多。 泛型类使用( <>)括起泛型类型,跟在类名后面。
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
GenericNumber类的使用是十分直观的,并且你可能已经注意到了,没有什么去限制它只能使用number类型。 也可以使用字符串或其它更复杂的类型。
let stringNumeric = new GenericNumber<string>();
stringNumeric.zeroValue = "";
stringNumeric.add = function(x, y) { return x + y; };
console.log(stringNumeric.add(stringNumeric.zeroValue, "test"));
与接口一样,直接把泛型类型放在类后面,可以帮助我们确认类的所有属性都在使用相同的类型。
如果我们直接对一个泛型参数取 length 属性, 会报错, 因为这个泛型根本就不知道它有这个属性
// 没有泛型约束
function fn <T>(x: T): void {
console.log(x.length) // 报错,因为目前不知道x是什么类型
}
我们可以使用泛型约束来实现
interface Lengthwise {
length: number;
}
// 指定泛型约束
function fn2 <T extends Lengthwise>(x: T): void {
console.log(x.length)
}
我们需要传入符合约束类型的值,必须包含必须 length 属性:
fn2('abc')
// fn2(123) // error number没有length属性
我在typescript类中有一个方法,看起来像这样varconfirmation=confirm("RunAgentJob?");if(confirmation){console.log('yes');}else{console.log('no');}我正在尝试将其转换为使用SweetAlert,因此我将其放入方法中。但是Typescript无法识别它抛出一个Cannotfindnameswalswal("hello");我已经导入了sweetalert如下我做错了什么?如果我尝试在一个普通的*.js文件中使用swal(),它会工作正常。仅当它位于*.ts文件中时。
我注意到TypeScript1.8版本支持F-BoundedPolymorphism.用外行的话来说,它是什么以及它有什么帮助?我假设由于此功能很早就包含在内,所以它一定非常重要。 最佳答案 这基本上意味着您拥有函数引用的泛型列表,并且在该泛型列表中,一种类型可以引用另一种类型,以定义两种泛型类型之间的关系。functionsomeFunction(t:T,u:U):T{returnt;}constdog=someFunction(newDog(),newCat());万岁!现在,有了有界泛型,它们可以相互引用来定义它们之间关系的界
我想在反射(reflect)类类型的键下的TypeScript(JavaScript)映射中存储一些信息。这是因为存储的数据实际上是静态的并且适用于每个类型,而不是每个实例。这是我声明Mapatm的方式:privatestaticfollowSetsByATN:Map=newMap();但是,number应该是类类型。如何实现? 最佳答案 如果您有一个对象({})作为映射,则键必须是字符串(或自动转换为字符串的数字)。在这种情况下,您可以使用toString()方法:classA{}console.log(A.toString())
是否有用于vscode的模块可以更新文件路径?例如如果我有:import'./someDir/somelib'然后我重命名或移动somelib,它会自动更新所有被引用的文件中的文件路径吗? 最佳答案 此功能是在VSCode1.24(trackingissue)中为JavaScript和TypeScript添加的当您移动或重命名文件时,系统现在会提示您查看是否要更新导入:这由javascript.updateImportsOnFileMove.enabled和typescript.updateImportsOnFileMove.ena
我正在尝试在我的新Angular2项目中导入文件。入口文件“main.ts”能够使用以下方式导入其他typescript文件:import{AppModule}from'./module/app.module';另一方面,“app.module.ts”无法导入没有文件扩展名的ts文件:import{AppComponent}from'../component/app.component';如果我在文件名中添加“.ts”,一切都会按预期进行...我的错误是什么?我假设我正在按照Angular指南(https://angular.io/docs/ts/latest/guide/webpac
我可能是错的,但通过查看typescriptsplayground,我注意到他们将类的方法与对象变量包装在一起,感觉每次我调用新对象时它可能会降低性能。例如类的TypescriptPlayground输出varFatObject=(function(){functionFatObject(thing){this.objectProperty='string';this.anotherProp=thing;}FatObject.prototype.someMassivMethod=function(){//manylinesofcode//...//...//...//.........
我开始使用Typescript并尝试将其应用到我的项目中。但是,我无法使用vue-resource等Vue.js插件。当我使用this.$http.post()我得到错误:errorTS2339:Property'$http'doesnotexistontype'typeofVue'.这是有道理的,因为我在类里面。但是我该怎么做呢?这是我的完整组件:SignupNamePleaseprovideaname.PasswordPleaseprovideapassword.importComponentfrom'vue-class-component'@Componentexportdefa
我正在使用TypeScript(2.4.2)首次涉足React(15.6.1),我正在尝试创建一个组件来表示可拖动的JSON字段。这是我的组件代码:import*asReactfrom"react";interfaceJsonFieldProps{name:string;type:string;indent:number;}exportclassJsonFieldextendsReact.Component{marginStyle={'text-indent':`${this.props.indent*15}px`};render(){return{this.props.name}:{
使用forwardRef时出现ts错误//[ts]Property'forwardRef'doesnotexistontype'typeofReact'.constMyComponent=React.forwardRef((props:Props,ref:any)=>...在ReactNative中,父组件抛出此错误:InvariantViolation:Elementtypeisinvalid:expectedastring(forbuild-incomponents)oraclass/function(forcompositecomponents)butgot:object有什么解
在我使用Angular的过程中,我被迫使用四种不同的方式来包含第3方库poliglot.js(对于多语言)。为了能够在我的Lang类中使用newPolyglot(...):exportclassLang{...constructor(){this.polyglot=newPolyglot({locale:'en'});...}...}我用这四种方法A.在我相当老的(2016年)angular2(基于framerworkangular2-webpack-starter)项目中(目前由于缺少require指令,该解决方案不起作用在新的Angular项目中):varPolyglot=requ