TypeScriptの使用は開発環境を標準化することですが、実際のランタイム環境では、TypeScriptは実際には制限的な役割を果たしません。
1.インストール
1.TypeScriptをインストールします
npm install typescript -g
インストールが完了したら、コンソールでtscコマンドを入力して、インストールが成功したかどうかを確認します。英語がたくさん出てくる場合は、インストールしたことを意味します。
これで、コンピューターにtypescriptを書き込むことができますが、必要に応じてtypescriptファイルを実行します。コードを実行する前に、tscコマンドを使用して.tsファイルを.jsファイルにコンパイルする必要があります。
tsc 文件名.ts
node 文件名.js
これは私たちの開発にとって非常に非効率的ですが、ts-nodeを使用してtypescriptファイルを直接実行し、中間のjs変換プロセスを調整することができます。
2.ts-nodeをインストールします
npm install -g ts-node
その後、ts-nodeコマンドを使用してtsファイルを直接実行できます。
ts-node 文件名.ts
2、タイプ注釈
JavaScriptは弱い型の言語であることは誰もが知っています。弱い型の言語は、標準化された開発プロセスには適していません。型アノテーションは、言語型を強化するためにTypeScriptによって提案されたソリューションです。したがって、TypeScriptも強い型の言語です。
たとえば、変数ageをタイプnumberとして定義した場合、別のタイプの値をそれにアタッチすることはできません。
let age: number;
age = 123;
上記の例に示されているように、TypeScriptの型注釈は「:」キーワードを使用することであり、宣言は次のように完了することができます:+データ型
データの種類 | キーワード |
---|---|
ストリング | ストリング |
数 | 数 |
ブール値 | ブール値 |
無効 | ボイド |
どれか | どれか |
未定義 | 未定義 |
ヌル | ヌル |
1.配列型の注釈
配列の均一型
const arr: number[] = [1, 2, 3];
配列内の型が均一ではありません
const arr: (number | string)[] = [1, "string", 2];
オブジェクト配列
const student: { name: string, age: number }[] = [
{ name: "小白", age: 21 },
{ name: "小黑", age: 18 },
];
2.タプルの使用
配列の欠如
配列を使用してビジネスを処理しているときに、配列内の要素の順序を変更すると、ビジネスロジックにエラーが発生しますが、配列の型アノテーションはエラーを報告しません。現時点では、タプルタイプComment(タイプ制約)を使用します。
// 如果数组中的元素顺序发生变化,数组的类型注释不报错,存在开发隐患
const beauty1: (string | number)[] = ["A", "student", 18]
const beauty2: (string | number)[] = ["A", 18, "student"]
// 使用元组中的类型约束可以解决此隐患
const beauties1: [string, string, number] = ["A", "student", 18]
const beauties2: [string, string, number] = ["A", 18, "student"] //报错!
三、インターフェースの使用
1.インターフェースの基本的なアプリケーション
インターフェースの簡単なアプリケーションとして、直接例を見てみましょう。たとえば、学生を例として取り上げましょう。
// 创建接口
interface Student {
name: string;
age: number;
exam?: number; //非必须属性在“:”前加上“?”即可
[propname: string]: any; //此接口允许添加新的属性
}
// 接口应用实例
const getStudent = (student: Student) => {
console.log("名字:" + student.name)
console.log("年龄:" + student.age)
// 做一个小判断,如果有成绩则输出成绩,没有成绩则输出提示
student.exam ? console.log("成绩" + student.exam) : console.log("此人无成绩")
}
// 数据
const xiaobai = {name: "小白", age: 21, exam: 90}
const xiaohei = {name: "小黑", age: 18}
// 以传值的形式调用方法
getStudent(xiaobai)
getStudent(xiaohei)
2.インターフェースのメソッド
上記の例に基づいて、Studentインターフェイスにメソッドwork()を格納する場合は、インターフェイスでメソッドを直接宣言し、その戻り値の型を制約できます。
interface Student {
name: string;
age: number;
exam?: number; //非必须属性在“:”前加上“?”即可
[propname: string]: any; //此接口允许添加新的属性
work(): string; //声明方法的返回值类型为string
}
インターフェイスでメソッドを宣言した後、後で使用できるように実際のオブジェクトでメソッドを完成させます。
const xiaobai = {
name: "小白", age: 21, exam: 90,
work() {
return "学习就是我的工作"
}
}
const getStudent = (student: Student) => {
console.log("名字:" + student.name)
console.log("年龄:" + student.age)
// 做一个小判断,如果有成绩则输出成绩,没有成绩则输出提示
student.exam ? console.log("成绩" + student.exam) : console.log("此人无成绩")
console.log(student.work())
}
3.インターフェース内のインターフェースへのクラスの実現
クラスを実装するときは、すべてのクラスを記述することを忘れないでください。そうしないと、エラーが報告されます。
class xinsheng implements Student {
name = "小白";
age = 21;
work() {
return "学习就是我的工作"
}
}
4.インターフェース間の継承
Studentインターフェースをベースとして使用できます。モニターインターフェースなど、Studentインターフェースに基づく新しいメソッドが必要な場合は、モニターにジョブshouzuoyeを収集するための特別なメソッドがあり、次のように実装できます。この:
interface Monitor extends Student {
shouzuoye(): string;
}
具体例:
interface Student {
name: string;
age: number;
exam?: number; //非必须属性在“:”前加上“?”即可
[propname: string]: any; //此接口允许添加新的属性
work(): string; //声明方法的返回值类型为string
}
// 接口的继承
interface Monitor extends Student {
shouzuoye(): string;
}
// 接口应用实例
const monitor = (teacher: Monitor) => {
console.log("名字:" + teacher.name)
console.log("年龄:" + teacher.age)
// 做一个小判断,如果有成绩则输出成绩,没有成绩则输出提示
teacher.exam ? console.log("成绩" + teacher.exam) : console.log("此人无成绩")
console.log(teacher.work())
console.log(teacher.shouzuoye())
}
const xiaohei = {
name: "小黑", age: 18,
work() {
return "学习就是我的工作"
},
shouzuoye(){
return "大家把作业交给我"
}
}
// 以传值的形式调用方法
monitor(xiaohei)
第四に、クラスの使用
typescriptのクラスの概念は、基本的にjavaおよびes6と同じであり、上記の例に違いはありません。
1.クラスの定義と使用
class Person {
name = "小黑";
age = 18;
say() {
return "我叫" + this.name
}
}
const p = new Person();
console.log(p.say());
2.クラスの継承
サブクラスは親クラスのすべてのプロパティとメソッドを継承し、直接呼び出すことができます。
class Student extends Person{
work(){
return "淦!我是学生,我得学习。"
}
}
const S = new Student();
console.log(S.say())
console.log(S.work())
3.クラスの書き換えとスーパーキーワードの使用
サブクラスは、親クラスのメソッドをオーバーライドできます。書き込みメソッドは、親クラスのメソッドを書き換えることです。親クラスのプロパティを呼び出す必要がある場合は、superキーワードを使用して呼び出すことができます。
class Student extends Person{
work(){
return "淦!我是学生,我得学习。"
}
// 重写父类中的say()方法
say(){
return super.say() + "很高兴认识你!"
}
}
const S = new Student();
console.log(S.say())
console.log(S.work())
4.クラスアクセスタイプと読み取り専用属性
クラスのアクセスタイプは、パブリック、プライベート、保護されています
公衆
Typescriptのデフォルトのアクセスタイプ。コードを記述するときにアクセスタイプを宣言しない場合、typescriptはデフォルトでパブリックタイプになります。
パブリックアクセスタイプは、クラスの内外で使用できます。たとえば、クラス内で変数を宣言する場合、クラス外で変数を直接呼び出すか、この変数を変更できます。
class Person{
public name:string;
public say(){
console.log(this.name)
}
}
const p = new Person();
p.say() //第一次
p.name = "小白"
p.say() //第二次
2つの出力結果は、クラスの内部変数が外部操作によって変更されたことを示しています。
民間
プライベートタイプは上記のパブリックタイプの正反対です。クラスの中括弧がない限り、操作で直接呼び出すことはできないことが理解できます(これは直接呼び出しであり、後でメソッドがあります)。プライベートタイプを操作します)。例を示します。
保護
保護タイプ。このタイプはプライベートに似ています。中括弧の直後に操作することはできませんが、保護されていると継承時に操作できます。
class Person{
protected name:string;
public say(){
console.log(this.name)
}
}
class Student extends Person{
name = "小黑";
sayHello(){
console.log(this.name)
}
}
const p = new Student();
p.say()
p.sayHello()
読み取り専用属性
クラスで変数を宣言するときに、変数のタイプを定義できます。属性の1つは読み取り専用と呼ばれます。この属性を持つ変数は、値を変更しようとするとエラーを報告します。
class Person{
public readonly name: string;
}
5.クラスコンストラクタ
通常のコンストラクター
コンストラクターであるtypescriptクラスにコンストラクターメソッドがあります。このメソッドを使用してクラスを初期化できます。typescriptのコンストラクターは、次のように作成すると非常に便利です。
class Person {
constructor(private name: string, public age: number) { }
}
const p = new Person("小黑", 21)
// console.log(p.name); //这里记得name是私有变量,外部不能直接调用
console.log(p.age)
サブクラスコンストラクタ
サブクラスのコンストラクターは非常に特殊です。継承拡張操作を実行したため、サブクラスでコンストラクターを作成するときにsuper()を使用する必要があります。そうしないと、typescriptでエラーが報告されます。
class Student extends Person {
constructor(private exam: number) {
super("小白",18);
}
}
6.クラスセッターとゲッター
開発プロセスでは、データのセキュリティを確保するために、データをプライベートとして定義することがよくあります。それを呼び出す場合は、setter()メソッドとgetter()メソッドまたはコンストラクターメソッドを使用します。
class Person {
constructor(private name: string, private age: number) { }
get getName() {
return this.name
}
set setName(name: string) {
this.name = name
}
get getAge() {
return this.age
}
set setAge(age: number) {
this.age = age
}
}
const p = new Person("小黑", 21)
p.setName = "小白"
console.log(p.getName)
7.抽象クラスの使用
抽象クラスabstractの導入により、標準化されたクラスの準備が容易になります。上記の例:たとえば
、学校に出入りするときに、どのユニット(クラス)から来たかを報告する必要があります。
abstract class School{
// 抽象类中的方法都需要加上abstract关键字,表示抽象方法
abstract baobei()
}
class Student extends School{
// 继承了抽象方法的类都必须对父类中的抽象方法进行具体化,具体跟类的重写是一样的
baobei(){
console.log("我是学生,是xx班的")
}
}
5.ジョイントタイプとタイプ保護
1.ジョイントタイプ
メソッドの1つが複数のタイプのパラメーター(パラメーター)を受け入れることができる場合、この時点で共用体タイプが使用されます。
class Student {
name: string;
jiaozuoye() { };
}
class Teacher {
name: string;
gaizuoye() { };
}
function f(parameter: Student | Teacher) { }
2.タイププロテクション
ただし、共用体型には別の問題があります。StudentとTeacherに2つの異なるメソッドがある場合、異なる型のパラメーターは、その型を継承する特別なメソッドがあるかどうかをどのように判断できますか?この問題を解決するために、型保護の概念を導入しました。
構文として
型アサーションとも呼ばれます。人為的な判断に相当します。たとえば、人の名前(名前属性)を「学生」と呼び、学生であると判断し、学生のメソッドjiaozuoye()を呼び出します。具体的な操作は以下のとおりです。
function f(parameter: Student | Teacher) {
if(parameter.name == "学生"){
(parameter as Student).jiaozuoye();
}
}
構文で
文法がわかりやすいです。たとえば、生徒と教師の違いは、宿題の提出方法と宿題の変更方法の違いにあります。パラメータに宿題を提出する機能がある場合は、彼を判断します。それ以外の場合は、彼を教師と判断します。構文で使用できる場合。
function f(parameter: Student | Teacher) {
if("jiaozuoye" in parameter){
parameter.jiaozuoye();
}else{
parameter.gaizuoye();
}
}
typeof構文
上記の例では、パラメーターはすべてカスタムタイプですが、一般的なタイプのタイプ保護戦略は何ですか?新しい例を挙げてください
function f(parameter1: string | number, parameter2: string | number) {
//使用typeof进行类型判断
if (typeof parameter1 === "string" || typeof parameter2 === "string") {
//字符串拼接
return `${first}${second}`;
}
return first + second;
}
instanceof構文
instanceofとtypeofの構文は非常に似ていますが、instanceofはクラスを保護するためにのみ使用できます。
// 我们先定义一个类,作为我们类型保护的基础
class NumberObj {
count: number;
}
// 实现一个相加的方法
function f(first: object | NumberObj, second: object | NumberObj) {
// 运用instanceof语句对类型进行判断
if (first instanceof NumberObj && second instanceof NumberObj) {
return first.count + second.count;
}
return 0;
}
6、ジェネリック
TypeScriptのジェネリックスの場合、これをパラメーター化された型として理解し、各パラメーターの型をパラメーターの形式にカプセル化できます。このカプセル化メソッドはジェネリックです。
1.関数ジェネリック
2つのパラメーターを受け取る関数を作成する場合、これらのパラメーターは両方とも文字列型または両方とも数値型であり、最後にスプライシング操作を実行します。
この関数は、実際には上記のジョイント型と型保護で実現できますが、この関数の条件を分析してみましょう。「この2つのパラメータは文字列型か両方の数値型かもしれません」と考えてみてください。この関数を呼び出すときに、この関数で渡されるパラメーターの種類を直接伝えませんか?答えはイエスです。ジェネリックはこの機能を実現できます。
function f<T>(one: T, two: T) {
return `${one}${two}`
}
f<string>("ok", "fine")
ここでもう1つ言及します。TypeScriptには型推論機能があるため、次のような関数を呼び出すときにジェネリックパラメーターを記述する必要さえありません。
f("ok", "fine")
もちろん、複数のジェネリックを定義することもできます。
function f<T, P>(one: T, two: P) {
return `${one}${two}`
}
f<string, number>("ok", 2)
2.ジェネリック型
クラスのジェネリック型を初期化します
クラスを作成し、2つのパラメーターを使用してコンストラクターを記述します。
class Student {
constructor(private name: string, private age: number) { }
}
パラメータの型をパラメータ化し、クラスの一般的な初期化を実現してから、単純な呼び出しを実現します。
class Student<T, P> {
constructor(private name: T, private age: P) { }
}
const stu = new Student<string, number>("小白", 21)
ジェネリック継承
上記のStudentの例に従うと、次のようなデータ構造になります。各StudentはNAME属性(文字列タイプ)を持つPersonインターフェイスから取得され、StudentオブジェクトでNAMEを取得する必要があります。
まず、インターフェースとゲッター関数を完成させます。
interface Person {
NAME: string
}
class Student<T> {
constructor(private name: T) { }
get getName() {
return this.name
}
}
現在のインターフェースPersonクラスとStudentクラスはまだ関連していません。次に、ジェネリック継承を使用して、Personの名前をStudentの名前に渡します。これを理解するときは、2つの名前の大文字と小文字に注意してください。クラスの場合、大文字はクラスに渡されるインターフェイスです。
interface Person {
NAME: string
}
class Student<T extends Person> {
constructor(private name: T) { }
get getName() {
return this.name.NAME
}
}
最後にそれを呼び出します。
const stu = new Student({ NAME: "小白" })
注意深く観察すると、コンストラクターを渡したときに、中括弧を使用してオブジェクトを直接渡したことがわかります。理由は実際には非常に単純です。Personは渡されるオブジェクトの説明と考えることができます。この説明はextendsステートメントを介してStudentのname属性に渡されます。最後に、オブジェクトを初期化すると、 initializeはオブジェクトですが、初期化するのはコンストラクター内の名前です。
最初は長い間この場所を見ていましたが、ようやく他人のコードを元に例を書いて、何度か読んでみると理解できました。