有两种方法:
第一种是tsc XXX.ts,这一操作将会使当前的ts文件生成一个转译后的对应的js文件,然后使用node直接运行这个js文件就可以啦。
第二种就是安装ts-node,直接使用ts-node XXX.ts命令来运行ts文件,这种的会比较方便一些,但是原理都是一样的
interface Animal {
name:string;
}
interface Cat {
name:string;
run():void // or run:() => void
}
// 这个时候虽然Animal和Cat在声明时并没有父子类之间的继承关系,但是ts在比较最终结构时,会自动认为:
Cat extends Animal {
run():void // or run:() => void
}
所以:
类型声明比类型断言更严格,我们最好优先使用类型声明,这也比类型断言的 as 语法更加优雅。
function test ():void{
console.log('测试函数没有返回值');
}
function test ():never{
throw new Error();
console.log('测试函数无法执行完成');
}
function add(
{ first, second }: { first: number; second: string }
) {
return first + second
}
const totalNum = add({first:5,second:'s'})
console.log(totalNum) //输出5s
一般来说,对于函数的类型注解,只需要写参数的类型就可以,返回值可以使用ts的类型推断来进行推断
const func = (str:string) =>{
return parseInt(str,10)
}
let temp:number|string = 23;
temp = 'abc'; //这里就不会报错了
// 一个数组的每项都是number
const arrNum: number [] = [2,1,5,8];
//一个数组的项既有number也有string
const arrNumStr: (number | string) [] = ['a',1,4,'b'];
enum specialTypeEnum {
月交 = 'M',
趸交 = 'SP',
'Y' = '年交',
'M' = '月交',
'SP' = '趸交',
'Q' = '季交',
'A' = '交至X岁'
}
export const payPeriodRule = (amount: string, unit: keyof typeof specialTypeEnum) => {
if(unit === 'SP' || amount === 'SP') {
return specialTypeEnum.SP;
};
}
// ts可以使用别名,简化数据类型的定义 ts alias,代码读起来更加清晰
type User = {
name:string,
age:number
}
const objArr1:User [] =[{
name:'LiMIng',
age:18
}]
//使代码读起来更加清晰易懂
#######附注:还可以使用class这种定义类的方式来定义数据的类型######
如下:
class PersonType {
name:string;
age:number;
}
const objArr1:PersonType [] =[{
name:'LiMIng',
age:18 //这里数组里面的对象多一项或者少一项都会报错
},
new PersonType()
]
//注意以下两种写法的区别
interface Person{
name:string
}
type Person = {
name:string
}
const arrPerson:Person = {
name:'abf'
}
//下面为接口interface的扩展
interface Person1 {
name:string; //name属性一定有
readonly school:string; //school是只读的string类型
age?:number; //age属性可有可无
[propName:string]:any; // 可以拥有类型为string的其他属性
say():string; //必有一个返回值为string的say函数
}
class student implements Person1 {
name:'Liming';
say() {
return 'remale';
}
} //类的定义也可以使用interface来进行数据类型的限制
interface teacher extends Person1 {
sex:string
}//接口的定义也可以使用其他接口的extends继承来进行数据类型的定义,这个时候teacher接口就继承了Person1接口上面对于数据类型的注解,还增加了对于sex属性的定义
上面例子中的两种其实都可以用来表示arrPerson这个对象的类型注解,但是区别在于interface只能代表一个对象的这样的数据类型,type却可以直接定义基础的数据类型,比如:
我可以使用 type Person = string; 这种形式来表示一个string类型的变量,但是interface却不可以。
另外,我们在日常的使用中,能使用interface就优先使用interface,不可以的再选择使用类型别名type,而且注意这种interface和typoe的定义在实际的ts编译为js代码的时候,不会作为逻辑代码存在于编译后的js中,只是ts帮助我们对于语法校验的工具而已
const arrTuple:[string,number,number] = ['sd',12,89]
//上面对于数组类型的定义方式,就是元组
//它限制了数组的固定赋值方式,即数组的项数,每一项的类型都已经固定
class Person {
protected name:string;
sayHi () {
console.log(this.name) //不会报错,属于类内
}
}
const person1 = new Person()
person1.name = 'LIly'; //会报错,属于类外了
class Teacher extends Person {
sayBye (){
console.log(this.name); //不会报错,属于在继承的子类中使用
}
}
class Person {
//传统写法
/*
public name:string;
constructor(value:string){
this.name = value
}
*/
//ts的新简化写法
constructor(puclic name:string){}
}
const person1 = new Person('Lily')
console.log(person1.name) //结果是Lily
class Demo {
private static instanceName:Demo;
private constructor(public name:string){
// console.log(this.name)
}
static creatInstance (name:string) { // 静态属性的声明static的用法是因为这样可以生成一个能在类上调用的方法,而并非生成的实例上面
if (!this.instanceName){
this.instanceName = new Demo(name);
}
return this.instanceName
}
}
const demo1=Demo.creatInstance('lily1');
console.log(demo1) //输出结果====> Demo { name: 'lily1' }
const demo2 = Demo.creatInstance('lily2');
console.log(demo2) //结果demo1和demo2打印出来是一样的结果,这样就实现了在类上进行初始化的创建的新对象都是一个一样的,只在第一次生成一个唯一的实例