【TypeScript】基础及问题汇总

1.js项目如何升级为ts?有何影响?

这是步骤 但是影响不是很清楚,感觉肯定两者要打架
但是ts编译成js可以这样
在这里插入图片描述

2.ts 基础类型都哪些,他们跟js的区别

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.ts为什么会流行?与ECMA新规范的关系?

TypeScript快速、简单,最重要的是,容易学习。
TypeScript支持面向对象的编程特性,比如类、接口、继承、泛型等等。
TypeScript在编译时提供了错误检查功能。它将编译代码,如果发现任何错误,它将在运行脚本之前突出显示这些错误。
TypeScript支持所有JavaScript库,因为它是JavaScript的超集。
TypeScript通过使用继承来支持可重用性。
TypeScript使应用程序开发尽可能的快速和简单,并且TypeScript的工具支持为我们提供了自动完成、类型检查和源文档。
TypeScript支持最新的JavaScript特性,包括ECMAScript 2015。
TypeScript提供了ES6的所有优点和更高的生产力。
TypeScript支持静态类型、强类型、模块、可选参数等。

4.tslint都能配置哪些功能?对开发流程有何影响?

5.如何使用ts实现类型约束,枚举等特性?

见后面

6.如何理解接口,泛型?

见后面

7.和JS的区别

在这里插入图片描述

8.TS的接口

  • 接口是在我们的应用程序中充当契约的结构。它定义了要遵循的类的语法,这意味着实现接口的类必须实现它的所有成员。它不能被实例化,但是可以被实现它的类对象引用。无论对象是否具有特定的结构,TypeScript编译器都使用接口进行类型检查

语法:

interface interface_name {    
          // 字段声明
          // 方法声明
}    

接口只是声明方法和字段,它不能用来建造任何东西。不需要将接口转换为JavaScript来执行,它们对运行时JavaScript没有任何影响。因此,它们的唯一目的是在开发阶段提供帮助。

9.你如何理解Typescript中的类?列出类的一些特性。

  • TypeScript是一种面向对象的JavaScript语言,支持OOP编程特性,比如类、接口等。与Java一样,类是用于创建可重用组件的基本实体。它是一组具有公共属性的对象。类是创建对象的模板或蓝图。它是一个逻辑实体。“class”关键字用于在Typescript中声明一个类。
class Student {    
    studCode: number;    
    studName: string;    
    constructor(code: number, name: string) {    
            this.studName = name;    
            this.studCode = code;    
    }    
    getGrade() : string {    
        return "A+" ;    
    }    
}    

类的特征是-

继承
封装
多态性
抽象

  • 类(Class):定义了一件事物的抽象特点,包含它的属性和方法
  • 对象(Object):类的实例,通过 new 生成
  • 面向对象(OOP)的三大特性:封装、继承、多态
  • 封装(Encapsulation):将对数据的操作细节隐藏起来,只暴露对外的接口。外界调用端不需要(也不可能)知道细节,就能通过对外提供的接口来访问该对象,同时也保证了外界无法任意更改对象内部的数据
  • 继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
  • 多态(Polymorphism):由继承而产生了相关的不同的类,对同一个方法可以有不同的响应。比如 Cat 和 Dog 都继承自 Animal,但是分别实现了自己的 eat 方法。此时针对某一个实例,我们无需了解它是 Cat还是 Dog,就可以直接调用 eat方法,程序会自动判断出来应该如何执行 eat
  • 存取器(getter & setter):用以改变属性的读取和赋值行为
  • 修饰符(Modifiers):修饰符是一些关键字,用于限定成员或类型的性质。
    比如 public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的
    private 修饰的属性或方法是私有的,不能在声明它的类的外部访问
    protected 修饰的属性或方法是受保护的,它和 private 类似,区别是它在子类中也是允许被访问的
  • 抽象类(Abstract Class):抽象类是供其他类继承的基类,抽象类不允许被实例化。抽象类中的抽象方法必须在子类中被实现
  • 接口(Interfaces):不同类之间公有的属性或方法,可以抽象成一个接口。接口可以被类实现(implements)。一个类只能继承自另一个类,但是可以实现多个接口

10.继承

继承可以通过使用extend关键字来实现。我们可以通过下面的例子来理解它。

class Shape {     
   Area:number     
   constructor(area:number) {     
      this.Area = area    
   }     
}     
class Circle extends Shape {     
   display():void {     
      console.log("圆的面积: "+this.Area)     
   }     
}    
var obj = new Circle(320);     
obj.display()  

11.模块(内部和外部)

在模块中声明的变量、函数、类和接口不能在模块外部直接访问。

//可以使用export关键字创建模块,也可以在其他模块中使用import关键字。

module module_name{  
    class xyz{  
        export sum(x, y){  
            return x+y;  
         }  
    }  
}  

在这里插入图片描述
“内部模块”现在称做“命名空间”。
“外部模块”现在则简称为“模块”模块在其自身的作用域里执行,而不是在全局作用域里;

  • 方法一:
/**
 * 新建一个db.ts 将数据库方法封装并且暴露出来
 * 暴露一个获取数据的方法
 */
export function getData():any[]{
    return [
        {
            name:'123',
            ahe:20
        },
        {
            name:'123425',
            age:30
        }
    ]
}

export function saveData():boolean{
    console.log('保存数据成功!')
    return true;
}

/**
 * 在index.ts文件中引入
 * 在这里引入我暴露的函数
 */

 import {getData} from './modules/db'

 console.log(getData());

  saveData();


  • 方法二
/**
 * 暴露一个获取数据的方法
 */
function getData():any[]{
    return [
        {
            name:'123',
            ahe:20
        },
        {
            name:'123425',
            age:30
        }
    ]
}

function saveData():boolean{
    console.log('保存数据成功!')
    return true;
}

export {getData, saveData}

/**
 * 在index.ts文件中引入
 * 在这里引入我暴露的函数
 */

 import {getData} from './modules/db'

 console.log(getData());

  saveData();


  • 方法三
/**
 * 使用export default 暴露数据
 */
function getData():any[]{
    return [
        {
            name:'123',
            ahe:20
        },
        {
            name:'123425',
            age:30
        }
    ]
}

function saveData():boolean{
    console.log('保存数据成功!')
    return true;
}

export default getData;

/**
 * export default 引入数据
 */

 import getData from './modules/db'


 console.log(getData());



  • 命名空间:

它封装了共享某些关系的特性和对象。名称空间也称为内部模块。名称空间还可以包括接口、类、函数和变量,以支持一组相关功能。

注意: 名称空间可以在多个文件中定义,并允许将每个文件都定义在一个地方。它使代码更容易维护。

namespace <namespace_name> {    
           export interface I1 { }    
           export class c1{ }    
}    

12.TypeScript是如何在函数中支持可选参数的?

我们可以通过使用问号符号(‘?’)来使用可选参数。这意味着可以或不可以接收值的参数可以附加一个’?”“可选的。

function Demo(arg1: number, arg2? :number) {              
}

因此,arg1总是必需的,而arg2是一个可选参数要放后面。
注意: 可选参数必须遵循要求的参数。如果我们想让arg1成为可选的,而不是arg2,那么我们需要改变顺序,arg1必须放在arg2之后。

function Demo(arg2: number, arg1? :number) {  
}  

13.什么是TypeScript Declare关键字?

我们知道所有的JavaScript库/框架都没有TypeScript声明文件,但是我们希望在TypeScript文件中使用它们时不会出现编译错误。为此,我们使用declare关键字。在我们希望定义可能存在于其他地方的变量的环境声明和方法中,可以使用declare关键字。

  • 例如,假设我们有一个名为myLibrary的库,它没有TypeScript声明文件,在全局命名空间中有一个名为myLibrary的命名空间。如果我们想在TypeScript代码中使用这个库,我们可以使用以下代码:
declare var myLibrary;  

TypeScript运行时将把myLibrary变量赋值为任意类型。

  • 例如,我们还可以用关键字来定义它的类型,帮助TypeScript 判断我们传入的参数类型对不对
declare var jQuery: (selector: string) => any;

jQuery('#foo');
//上例的编译结果是:

jQuery('#foo');

通常我们会把类型声明放到一个单独的文件中,这就是声明文件

// jQuery.d.ts

declare var jQuery: (string) => any;

我们约定声明文件以 .d.ts 为后缀。
然后在使用到的文件的开头,用「三斜线指令」///表示引用了声明文件

/// <reference path="./jQuery.d.ts" />

jQuery('#foo');

14.解释TypeScript中的泛型?

TypeScript泛型是一个提供创建可重用组件方法的工具。它能够创建可以处理多种数据类型而不是单一数据类型的组件。泛型在不影响性能或生产率的情况下提供类型安全性。泛型允许我们创建泛型类、泛型函数、泛型方法和泛型接口。

在泛型中,类型参数写在开(<)和闭(>)括号之间,这使得它是强类型集合。泛型使用一种特殊类型的类型变量,它表示类型。泛型集合只包含类似类型的对象。

function identity<T>(arg: T): T {      
    return arg;      
}      
let output1 = identity<string>("myString");      
let output2 = identity<number>( 100 );    
console.log(output1);    
console.log(output2);     

15.TS的“接口”和“type”语句有什么区别?

interface X {  
    a: number  
    b: string  
}  
type X = {  
    a: number  
    b: string  
};  

在这里插入图片描述

16.什么是TypeScript中的类型断言?

类型断言的工作方式类似于其他语言中的类型转换,但是它不像其他语言一样执行C#和Java那样的类型检查或数据重组。类型转换附带运行时支持,而类型断言对运行时没有影响。但是,类型断言仅由编译器使用,并向编译器提供有关我们希望如何分析代码的提示。

let empCode: any = 111;     
let employeeCode = <number> code;     
console.log(typeof(employeeCode)); // : number  

例将 something 断言成 string



function getLength(something: string | number): number {
    if ((<string>something).length) {
        return (<string>something).length;
    } else {
        return something.toString().length;
    }
}

17.TypeScript的as语法是什么?

as是TypeScript中类型断言的附加语法,引入as-语法的原因是原始语法()与JSX冲突。

例子

let empCode: any = 111;     
let employeeCode = code as number;   

当使用带有JSX的TypeScript时,只允许as风格的断言。

18.什么是JSX?我们可以在TypeScript中使用JSX吗?

JSX只不过是带有不同扩展名的Javascript。Facebook提出了这个新的扩展,以便与JavaScript中类似xml的HTML实现区分开来。

JSX是一种可嵌入的类似xml的语法。它将被转换成有效的JavaScript。JSX随着React框架而流行起来。TypeScript支持嵌入、类型检查和直接将JSX编译成JavaScript。

要使用JSX,我们必须做两件事。

使用.tsx扩展名命名文件
启用jsx选项

19.什么是Rest参数?

rest参数用于向函数传递零个或多个值。它是通过在参数前加上三个点字符(‘…’)来声明的。它允许函数在不使用arguments对象的情况下拥有可变数量的参数。当我们有不确定数量的参数时,这是非常有用的。

rest参数要遵循的规则:

一个函数中只允许有一个rest参数。
它必须是数组类型。
它必须是参数列表中的最后一个参数。

function sum(a: number, ...b: number[]): number {    
 let result = a;    
 for (var i = 0; i < b.length; i++) {    
 result += b[i];    
 }    
 console.log(result);    
}    
let result1 = sum(3, 5);    
let result2 = sum(3, 5, 7, 9);   

20.解释TypeScript的Enum枚举类型?

枚举或枚举是一种数据类型,允许我们定义一组命名常量。使用枚举可以更容易地记录意图,或者创建一组不同的案例。它是相关值的集合,可以是数值或字符串值。

例子

enum Gender {  
  Male,  
  Female  
  Other  
}  
console.log(Gender.Female); // : 1  
// 我们还可以通过enum值的number值来访问它
console.log(Gender[1]); // : Female

21.解释相对模块和非相对模块的导入

  • 非相对
  • 非相对导入可以相对于baseUrl解析,也可以通过路径映射解析。换句话说,我们在导入任何外部依赖项时使用非相对路径。 例子:
 import * as $ from “jquery”; 
 import { Component } from “@angular/core”;
  • 相对
  • 相对导入可以用于我们自己的模块,这些模块保证在运行时维护它们的相对位置。相对导入以/、./或…/开头。 例子:
 import Entry from./components/Entry”; 
 import {DefaultHeaders} from../constants/http”;

22.什么是匿名函数?

匿名函数是声明时没有任何命名标识符的函数。这些函数是在运行时动态声明的。与标准函数一样,匿名函数可以接受输入和返回输出。匿名函数在初始创建之后通常是不可访问的。

例子

let myAdd = function(x: number, y: number): number {   
	return x + y;   
};  
console.log(myAdd())  

23.什么是声明合并?

声明合并是编译器随后合并两个或多个独立声明的过程。将具有相同名称的声明声明为单个定义。这个合并的定义具有两个原始声明的特性。

最简单也是最常见的声明合并类型是接口合并。在最基本的层次上,merge将两个声明的成员机械地连接到一个具有相同名称的接口中。

例子

interface Cloner {  
    clone(animal: Animal): Animal;  
}  
interface Cloner {  
    clone(animal: Sheep): Sheep;  
}  
interface Cloner {  
    clone(animal: Dog): Dog;  
    clone(animal: Cat): Cat;  
}  
这三个接口将合并为一个单独的声明

interface Cloner {  
    clone(animal: Dog): Dog;  
    clone(animal: Cat): Cat;  
    clone(animal: Sheep): Sheep;  
    clone(animal: Animal): Animal;  
}  

注: 在TypeScript中不是所有的合并都允许。目前,类不能与其他类或变量合并。

24.TypeScript中的方法重写是什么?

如果子类(子类)具有与父类中声明的相同的方法,则称为方法覆盖。换句话说,在派生类或子类中重新定义基类方法。

方法重写的规则

该方法必须具有与父类相同的名称
该方法必须具有与父类相同的参数。
必须有一个IS-A关系(继承)。
例子

class NewPrinter extends Printer {  
    doPrint(): any {  
        super.doPrint();  
        console.log("Called Child class.");  
    }  
    doInkJetPrint(): any {  
        console.log("Called doInkJetPrint().");  
    }  
}  
let printer: new () => NewPrinter;  
printer.doPrint();  
printer.doInkJetPrint();  

25.Lambda/箭头函数是什么?

ES6版本的TypeScript提供了定义匿名函数的简写语法,也就是用于函数表达式。这些箭头函数也称为Lambda函数。lambda函数是没有名称的函数,箭头函数省略了function关键字。

例子

let sum = (a: number, b: number): number => {    
            return a + b;    
}    
console.log(sum(20, 30)); //returns 50    

在上面,?=>?是一个lambda操作符,(a + b)是函数的主体,(a: number, b: number)是内联参数。

posted @ 2020-10-19 10:14  嗨Sirius  阅读(132)  评论(0编辑  收藏  举报