typescript是JavaScript的、带有类型的超集,并且能够编译为普通的JavaScript。它是一种建立在JavaScript上的编程语言,也是一种工具。它是一个强大的编译器,你可以在代码上运行,将typescript编译为JavaScript。
它为JavaScript添加新功能和优势。但是,typescript在JavaScript环境无法运行,浏览器无法执行类型脚本。
优点:类型检查;代码补全;易于维护;入门简单。它使编写干净的代码变得非常容易。
typescript添加类型和数据对类型非常重要,我们必须更明确地了解事情的运作方式,可以避免很多使用类型的意外和不必要的错误。typescript是可配置的。
typescript可以在开发过程中帮助我们进行检查,允许我们更早地修复错误。typescript只能在开发期间获得支持,不在运行时,因为这些类型脚本功能和检查没有内置到JavaScript引擎中,这样的逻辑就不能在浏览器中执行,它只能在开发期间执行。
首先,确保你的电脑安装了Node.js。
输入命令npm install -g typescript;把typescript编译器安装到全局,这样,所有的typescript项目都可以使用它。安装完成,我们可以使用 tsc 命令来执行 typescript 的相关代码,输入tsc - v命令来查看版本号,看到typescript的版本号说明安装成功了。

新建一个LearningTypeScript文件夹,用VSCode打开。在这个文件夹中新建一个demo01.ts文件。里面写一点内容,如下所示。

在终端输入tsc demo01.ts,TypeScript编译器就可以把ts文件编译成js文件了。

可以看到在文件夹中生成了一个新的demo01.js文件。

运行一下,输入:node demo01.js,可以看到输出了数字13。

那么,JavaScript的版本这么多,tsc如何知道应该编译成哪种版本呢?
tsc默认会编译成ES3版本。我们试一下在demo01.ts文件中加一个async异步函数,它是ES1017版本的,应该如何编译呢?

我们可以在文件夹中新建一个tsconfig.json配置文件,通过compilerOptions属性来配置tsc编译器,target⽤于指定要编译成的版本,这里指定ES2017。

现在,再次运行tsc,后面不需要加文件名了。因为有了tsconfig.json文件之后,这个文件夹会自动成为typescript的项目,tsc会自动找到ts文件并进行编译。如果制定了文件名,那么这个配置文件的配置就会被忽略了。

打开js文件,发现和ts文件的async函数一样。

给变量定义类型有两种方式,一种是隐式的,一种是显式的。
隐式类型由typescript根据变量的值来推断类型。代码写法与js一样,但是,它后面不能用其他类型的值给它重新赋值。比如定义一个let a = 10,a = ‘hello’;这样编译器就会报错,提示“hello字符串不能赋值给数字类型”!
let a = 10;
a = 'hello';
基本类型与javascript一样:boolean number string undefined null 。显示类型的定义,就跟之前运行的ts代码示例一样,用冒号加类型来显示地规定这个变量是什么类型的。
// : boolean 表示是布尔类型的
let b: boolean = true;
// : number 表示是数字类型的
let c: number = 22;
// 字符串类型
let s: string = 'john';
// undefined
let u: undefined = undefined;
// null
let n: null = null;
如果想让一个变量可以是任何类型的,那么可以把它的类型定义为any。声明为 any 的变量可以赋予任意类型的值。
例如:给a一个数字类型的值,再改成字符串,这时候就不报错啦。
let a:any = 10;
a = "hello"
类型也可以用在函数的参数和返回值中。
比如下面的例子中:定义一个加法函数,接收类型为number的两个参数a、b;返回值的类型也是number,返回值的类型定义在参数列表的小括号后面;再后面才是函数体。
//类型也可以用在函数的参数和返回值中
// 比如:定义一个加法函数,接收类型为number的参数n1、n2;返回值的类型也是number,返回值的类型定义在参数列表的小括号后面;再后面才是函数体。
// 实例中定义了函数 add(),返回值的类型为 number。
// add() 函数中定义了两个 number 类型的参数,参数之间用,分隔,函数内将两个参数相加并返回。
function add(n1: number, n2: number): number {
// 通过使用 return 语句就可以实现返回值,在使用return语句时,函数会停止执行,并返回指定的值。
// 返回a+b
return n1 + n2;
}
// 如果函数没有返回值,可以使用void类型表示函数没有返回值。如下所示:
// function add(n1:number,n2:number):void{
// console.log(n1+n2)
// }
// 调用函数
// 不能使用字符串变量来接收函数的返回值,会报错。比如:let res:String = add(1,2);提示“number类型不能赋值给string类型!”
// 不能给函数传递字符串。比如:add("1",2);那么编译器会提示“字符串1不能传给number类型的函数!”
// 调用函数时,必须传递与参数列表一样的参数,不像js,可以不传或只传一个参数。比如:add(1);就会提示“没有给n2传值!”
// 在 TypeScript 函数里,如果我们定义了参数,则我们必须传入这些参数。除非将这些参数设置为可选,可选参数使用问号标识 ?。
add(1, 2);
如果一个变量可以有多个类型,但是又不想使用any破坏类型检查,就可以使用组合类型。组合类型使用 | 来定义。
比如:一个变量p既可以是数字类型也可以是字符串类型。
let p:number | string = 10;
p = "hello typescript";
不过,代码这样看起来不大方便。并且这个组合类型只能给p使用。如果有别的变量也是数字或字符串类型,还要重复定义。
要解决这个问题,可以使用type关键字给这个组合类型起一个别名,让代码更易读,也方便变量使用。
例子如下:
// 定义一个type名为NumStr。定义了一个number | string的联合类型变量,因此给变量赋值数值或字符串都是可以的。
type NumStr = number | string;
// p变量定义一个数字
let p:NumStr = 10;
p = "hello typescript";
// q变量定义一个字符串值
let q:NumStr = "hi";
// 组合类型也可以直接使用字面值来定义,这样,就规定了一个变量的取值范围。
// 比如:想让字符串类型的变量只能去on或者off两者之一;那么就可以这么定义,在变量o后面直接使用on off
let o: "on" | "off" = "on";
// 可以给它赋值off
o = "off";
// 但是,不能给它赋值除了on、off之外的值,会报错,提示"hah不能赋值给用on或off定义的类型里面!"
// o = "hah";
TypeScript 中,使用interfaces接口,接口是用来规范一个对象里应该都有哪些属性,包括它的名字和它的类型。接口一般首字母大写。
定义的变量⽐接⼝多了或者少了⼀些属性都是不允许的。
// 比如:有一个person文档变量,我想让它有name和hobby属性,并且都是String类型的,那么我们可以使用接口来定义一个person类型。
// 定义一个接口Person 接口首字母要大写
interface Person {
// 大括号里面有属性和类型;每个属性后面用分号分隔
name:string;
hobby:string;
}
// 定义一个person对象,使用Person接口类型;person对象实现了接口Person的属性和方法。
// 对象里面只能包括接口里定义的属性。对象里面也不能少定义属性,会提示“缺少属性!”;
let person: Person={
name:"ym",
hobby:"唱歌",
}
可选属性:有时我们希望不要完全匹配接口中的所有属性,那么可以用可选属性,表示该属性可以不存在。
// 带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?
interface Person1 {
name: string;
hobby:string;
// age为可选属性
age?: number;
}
let James: Person1 = {
name: 'James',
hobby:"跑步",
};
给数组规定类型,可以保证里面的元素都是同一个类型,以防在统一处理数组元素时,混进来其他类型的元素,导致异常。或者防止意外给数组元素赋了其他类型的值。
要定义数组类型的方法有如下两种:
第一种,可以在类型后面加一对空的方括号 [],表示由此类型元素组成的一个数组;
第二种方式是使用数组泛型,Array<元素类型>。
// 定义一个number类型的数组
// 第一种,可以在类型后面加一对空的方括号 [],表示由此类型元素组成的一个数组
let arr1: number[] = [1, 2, 3];
// 第二种方式是使用数组泛型,Array<元素类型>。
// 泛型属于面向对象语言中比较高级的特性。 应用在数组身上,同样可以用来规定数组中元素的类型。
let arr2: Array<number> = [1, 2, 3];
我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组。
// TypeScript中有一个元组tuple。它是一个有限元素数量的数组(固定的数组),并且长度也是固定的。但是,每个元素需要分别指定是什么类型。
// 比如:这里有一个三元组就是这个数组中有三个元素。规定第一个元素是number类型,第二个元素是string类型,第三个元素是boolean类型。
// 声明一个元组并初始化
let mytup:[number,string,boolean] = [1,"joy",true];
访问元组:元组中元素使用索引来访问,第一个元素的索引值为 0,第二个为 1,以此类推第 n 个为 n-1。
元组运算:我们可以使用以下两个函数向元组添加新元素或者删除元素。
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po