zoukankan      html  css  js  c++  java
  • 【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)是内联参数。

  • 相关阅读:
    谷歌浏览器默认字体最小12px的解决方案
    字符编码笔记:ASCII,Unicode和UTF8 (转)
    关于URL编码(转)
    .net 应用程序域的影子复制
    .net动态加载程序集和影子复制(Dynamic Load Assembly and Shadow Copy)
    关于.net影子复制的问题
    来得有点晚,不过博客不分先后 :)
    App Domains and dynamic loading
    AppDomain and Shadow Copy
    Delphi实现软件自动更新源代码
  • 原文地址:https://www.cnblogs.com/SiriusZHT/p/14310734.html
Copyright © 2011-2022 走看看