首页 > 技术文章 > TypeScript

universe-cosmo 2019-07-18 17:58 原文

/*
* 布尔值 boolean
*/
let isDone: boolean = false;

// 因为Boolean返回的是对象,所以无法使用普通数据类型boolean
// let createdByNewBoolean: boolean = new Boolean(1);

/*
* 字符串 string
*/
let myName: string = 'Tom';
let myAge: number = 25;
let sentence: string = `Hello, my name is ${myName}.
I'll be ${myAge + 1} years old next month.`;

/*
* 函数 function
*/
function alertName(): void {
    alert('My name is Tom');
}

/* 接口 interface
interface Person {
    name: string;
    age?: number;
    [propName: string]: string;
}
let tom: Person = {
    name: 'Tom',
    age: 25,
    gender: 'male'
};
*/
// ts中一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集(特别注意)
// 有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性
// 注意,只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候
interface Person {
    readonly id: number;  // 此处只读约束只约束第一次给Person赋值的时候,而不是第一次给属性id赋值的时候(所以重新给id赋值会失败)。
    name: string;
    [propName: string]: string | number;  // 任意类型的属性会覆盖任意确定属性和可选属性的值,必须为任意属性值的子类型。
    age?: number;
}


/* 
* 数组类型(在数组中使用any类型,表示数组中允许出现任意类型)
*/
let arrayNumber: number[] = [1, 2, 3, 4, 5];  // 最简单的数组类型赋值方法(数组的项中不允许出现其他的类型)
// 数组泛型
let arrayNumberType: Array = [true, false];
// 用接口表示数组
interface NumberArray {
    [index: number]: string;
}
let fibonacci: NumberArray = ["1", "1", "2", "3", "5"];
// 类数组(和数组的表示方法不同)
function sum() {
    let args: {
        [index: number]: number;
        length: number;
        callee: Function;
    } = arguments;  // 可以用TypeScript定义好的类型IArguments来表示,等同于此接口,其它的类数组还有NodeList, HTMLCollection等。
    return args;
}


/* 
* 函数类型
*/
// 函数声明
function sumFunction (x: number, y: number): number {
    return x + y;
}
// 函数表达式(variableFunction No declare 则自动推断类型)
let variableFunction = function (x: number, y: number): number {
    return x + y;
}
// 函数表达式手动声明类型(需要注意此处的=>与ES6中的箭头函数的区别)
let variableDeclareFunction: (x: number, y: number) => number = function (x: number, y: number): number {
    return x + y;
}
// 函数表达式使用接口定义类型
interface functionInterface {
    (x: string, y: string): string
}
let variableStringFunction: functionInterface = function (x: string, y: string): string {
    return x + y;
}
// 函数可选参数的约束方法(需要注意的是在可选参数之后无法定义必须参数)
function guessArgumentsFunction (x: string, y?: string): string {
    return x + y;
}
// 在ES6中可以使用参数默认值写法(TypeScript会将添加了默认值的参数识别为可选参数,这种情况下的可选参数不受「可选参数必须接在必需参数后面」的限制)
function buildName (firstName: string = 'Tom', lastName: string): string {
    return "buildNameValue";
}
// 在ES6中可以使用...rest获取函数中的剩余参数(TypeScript中可以使用一个数组类型来定义它)
function guessPush (array: any[], ...items: any[]): any[] {
    return ["string", "any"];
}
// 重载(可以使用重载来进行约束参数类型和返回值的类型:folowing example.)
// TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
    if (typeof x === 'number') {
        return parseInt(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
}


/* 类型断言(当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法「比如(string|number): 访问length属性只有string有,则会编译失败」) */
// 类型断言不是类型转换,断言成一个联合类型中不存在的类型是不允许的。
// 在 tsx 语法(React 的 jsx 语法的 ts 版)中必须使用 (值 as 类型) 这种方法
function toBoolean(something: string | number): number {
    return (something).length;
}


/* declare file */
// declare var 并没有真的定义一个变量,只是定义了全局变量 jQuery 的类型,仅仅会用于编译时的检查,在编译结果中会被删除。
// 通常我们会把声明语句放到一个单独的文件(jQuery.d.ts)中,这就是声明文件。
// 声明文件必需以 .d.ts 为后缀。
// 其余新语法可在 https://ts.xcatliu.com/basics/declaration-files 中查询
// 常用的框架类型声明文件可在 https://microsoft.github.io/TypeSearch/ 中查询
declare var jQuery: (selector: string) => any;


/*
* 可以使用type设置类型别名,常用语联合类型
*/
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
    if (typeof n === 'string') {
        return n;
    } else {
        return n();
    }
}

 

推荐阅读