Type Script真香シリーズ-タイプ推論とタイプ互換性
8742 ワード
前言
Type Script真香シリーズの内容は中国語の文書を参照しますが、文書の例とほとんど重複しません.一部のところについても深く研究しています.また、いくつかの例の結果は、コードに誤りがない後、JavaScriptにコンパイルされたものです.実際にType Scriptを見たいなら、JavaScriptとしてコンパイルされたコードは、Type Scriptのオンラインアドレスにアクセスして、操作して、より印象的です.
類型推論
基礎
Type Scriptのタイプ推論は、変数のタイプを明確に指定していない場合、Type Scriptは変数のデータタイプを自動的に推定することができます.
上記の例は簡単ですが、私達が定義した変数が配列という比較的複雑なタイプの場合、Type Scriptはその中のメンバーによって最適な汎用タイプを推定します.
上記の例は右から左にかけて判定されるタイプです.Type Scriptタイプの推論も逆の方向から推測されることがあります.これは「コンテキスト分類」と呼ばれ、文脈分類によって表現の種類と位置が関係する場合があります.以下の例は関数のセクションにあります.
基礎
Type Scriptのタイプの互換性は、他のタイプに与えられるかどうかを判定するために使用されてもよい.ここで二つの概念を理解します.
構造タイプ:1つはそのメンバーだけを使用してタイプを記述する方法.
名義のタイプ:はっきりと指摘したり、宣言したりするタイプ、例えばc葃、java.
Type Scriptのタイプ互換性は構造のサブタイプに基づいています.以下の例:
Type Script構造型システムの基本的なルールは、xがyに互換性があるなら、yは少なくともxと同じ属性を持つ.次の例のように:
比較関数
パラメータが違います
上記の例はいくつかのオリジナルのタイプまたはオブジェクトの比較です.関数間の比較を見てみます.
関数パラメータの双方向共変
双方向協働は協働とインバータを含む.協働とはサブタイプの互換性のある親タイプのことで、インバータは正反対です.
オプションパラメータとレスポンスパラメータの互換性については、以下の例を参照してください.
リロードについては、まずjavaの定義を見てみます.同じクラスでは、同じ名前の関数が一つ以上存在することができます.彼らのパラメータの数やパラメータの種類が違っていればいいです.戻り値タイプに関係なく、パラメータリスト(パラメータの個数、パラメータの種類、パラメータの順序)のみを見ます.
Type Scriptにおける関数の再負荷とjavaにおける違いは、Type Scriptにおける関数の負荷はパラメータタイプのみです.
次に、戻り値の種類をどう比較するかを見ます.ソース関数の戻りのタイプは、ターゲット関数の戻り値のサブタイプでなければなりません.
列挙のタイプと数字のタイプは互換性があります.
クラスの基本比較
Type Scriptでは、例示的なメンバーと方法だけが比較され、静的なメンバーと構造関数は比較されない.
クラスのプライベートメンバーと保護されたメンバー
クラスのプライベートメンバーと保護されたメンバーの互換性の比較規則は同じです.二つの種類を比較する時、二つの種類に分けて見ます.二つの種類は親子で、父類に私有メンバーがいる場合、二つの種類は互換性があります.2つのクラスが同じクラスのクラスであり、また、同じクラスにプライベートまたは保護されたメンバーが含まれている場合は、互換性がありません.次の二つの例を見てください.親子類:
Type Script汎型の互換性は二つの場合に分けられます.一つはタイプパラメータがメンバーに使用されていません.もう一つは、タイプパラメータがメンバーによって使用されることである.まずタイプパラメータがメンバーに使用されていない場合を見ます.
参照
https://github.com/zhongsp/Ty... https://github.com/jkchao/typ...
最後に
文章の中には自分の理解を入れるところがあります.正確でないところや間違っているところがあれば、ご指摘ください.
Type Script真香シリーズの内容は中国語の文書を参照しますが、文書の例とほとんど重複しません.一部のところについても深く研究しています.また、いくつかの例の結果は、コードに誤りがない後、JavaScriptにコンパイルされたものです.実際にType Scriptを見たいなら、JavaScriptとしてコンパイルされたコードは、Type Scriptのオンラインアドレスにアクセスして、操作して、より印象的です.
類型推論
基礎
Type Scriptのタイプ推論は、変数のタイプを明確に指定していない場合、Type Scriptは変数のデータタイプを自動的に推定することができます.
let a = 3;
a = 4;
a = "s"; // ,"s" number
上記の例から、変数aを定義した後、値を賦課すると、Type Scriptは変数aの種類を自動的に推定してくれることが分かります.変数aに文字列を割り当てると、コードのエラーメッセージが表示されます.このような書き方はJavaScriptでは可能ですが、Type Scriptでは制限されています.let a = {
p: "",
c: 0
};
a.p = " ";
a.p = 1; // ,1 string
最適共通タイプ上記の例は簡単ですが、私達が定義した変数が配列という比較的複雑なタイプの場合、Type Scriptはその中のメンバーによって最適な汎用タイプを推定します.
let a = [1, 2, null];
a=["s"]; // , "string" "number | null"
コンテキストのタイプ上記の例は右から左にかけて判定されるタイプです.Type Scriptタイプの推論も逆の方向から推測されることがあります.これは「コンテキスト分類」と呼ばれ、文脈分類によって表現の種類と位置が関係する場合があります.以下の例は関数のセクションにあります.
function sum(a: number, b: number){
return a + b;
}
戻り値のタイプは指定されていませんが、Type Scriptは自動的に上から下まで推定されます.number。
let man = {
a: 1,
b: "james",
play: (s: string) => {
return s
}
}
man.play = function (s){
return s + "s"
}
タイプ互換性基礎
Type Scriptのタイプの互換性は、他のタイプに与えられるかどうかを判定するために使用されてもよい.ここで二つの概念を理解します.
構造タイプ:1つはそのメンバーだけを使用してタイプを記述する方法.
名義のタイプ:はっきりと指摘したり、宣言したりするタイプ、例えばc葃、java.
Type Scriptのタイプ互換性は構造のサブタイプに基づいています.以下の例:
interface IName {
name: string;
}
class Man {
name: string;
constructor() {
this.name = " ";
}
}
let p: IName;
p = new Man();
p.name;
上のコードはType Scriptで間違いないですが、javaなどの言語でエラーが発生します.Man類は明確な説明がないので、INameインターフェースを実現しました.上の例は何も反映されていないと感じる人がいるかもしれませんが、次のような互換性のない例を見ます.let man: string = " ";
let age: number = 20;
man = age; // , number string
age = man; // , string number
互換性のある例を見てください.let man: any = " ";
let age: any = 123
man = age; //123
構造化Type Script構造型システムの基本的なルールは、xがyに互換性があるなら、yは少なくともxと同じ属性を持つ.次の例のように:
interface IName {
name: string;
}
let x: IName;
let y = {name: " ", age: 123, hero: true};
x = y; //{name: " ", age: 123, hero: true}
ここでコンパイラはxの各属性をチェックします.yにも対応する属性が見つけられますか?上のyはx互換性の要求に適合しています.即ちx互換yです.interface IName {
name: string;
age: number
}
let x: IName;
let z = { name: " ", cool: true };
x = z; //
ここでコンパイラがチェックすると、zにはxの「age」という属性がないことが分かりますので、xとzは互換性がありません.比較関数
パラメータが違います
上記の例はいくつかのオリジナルのタイプまたはオブジェクトの比較です.関数間の比較を見てみます.
let x = (a: number) => 0;
let y = (b: number, c: string) => 0;
y = x;
x = y; //
xがyに割り当てられるかどうかを見るには、xとyのパラメータリストを先に見ます.xの各パラメータはyの中に対応するタイプのパラメータを見つけなければなりません.パラメータの種類が対応していれば、パラメータの名前は構いません.上記の例ではxのパラメータはyに対応するパラメータを見つけることができますので、値の割り当ては許可されますが、逆にyはxに値を付けることができません.関数パラメータの双方向共変
双方向協働は協働とインバータを含む.協働とはサブタイプの互換性のある親タイプのことで、インバータは正反対です.
let man = (arg: string | number) : void => {};
let player = (arg: string) : void => {};
man = player;
player = man;
オプションとレスポンスパラメータオプションパラメータとレスポンスパラメータの互換性については、以下の例を参照してください.
let man = (x: number, y: number) => {};
let work = (x?: number, y?: number) => {};
let play = (...args: number[]) => {};
man = work = play;
play = work = man;
関数の再ロードリロードについては、まずjavaの定義を見てみます.同じクラスでは、同じ名前の関数が一つ以上存在することができます.彼らのパラメータの数やパラメータの種類が違っていればいいです.戻り値タイプに関係なく、パラメータリスト(パラメータの個数、パラメータの種類、パラメータの順序)のみを見ます.
Type Scriptにおける関数の再負荷とjavaにおける違いは、Type Scriptにおける関数の負荷はパラメータタイプのみです.
function sum(a: number, b: number): number;
function sum(a: string, b: string): string;
function sum(a: any, b: any) {
let result = null;
if (typeof a === "string" && typeof b === "string") {
result = a + " " + b + " ";
} else if (typeof a === "number" && typeof b === "number") {
result = a + b
}
return result;
}
sum(" ", " ");
sum(1, 1);
リロードされた関数の場合、ソース関数の各リロードはターゲット関数に対応する関数署名を見つけます.以下のような方法はエラーです.function sum(a: number, b: number): number; // ,
function sum(a: string, b: string): string{
return a + b;
};
以下の例はType Scriptでも再負荷できません.function sum(a: number, b: number): number{ // ,
return a + b;
};
function sum(a: any, b: any): any{ // ,
return a + b;
};
戻り値が違います次に、戻り値の種類をどう比較するかを見ます.ソース関数の戻りのタイプは、ターゲット関数の戻り値のサブタイプでなければなりません.
interface IMan {
x: string;
y: number;
}
interface IPlayer {
x: string;
y: number;
z: number;
}
let man = (): IMan => ({ x: " ", y: 0 });
let player = (): IPlayer => ({ x: " ", y: 0, z: 0 });
man = player;
player = man; //
上からわかるように、playerはmanのサブタイプなので、man互換playerです.以下の例もこの点を示している.interface IMan {
x: string;
y: number;
}
interface IPlayer {
a: string;
b: number;
c: number;
}
let man = (): IMan => ({ x: " ", y: 0 });
let player = (): IPlayer => ({ a: " ", b: 0, c: 0 });
man = player; //
player = man; //
列挙列挙のタイプと数字のタイプは互換性があります.
enum Man {
name,
age,
}
let num = 1;
let num2 = 2;
let enumNum: Man.name = num;
num2 = Man.name;
異なる列挙の間は互換性がない:enum Man {
name,
age,
}
enum Player {
name,
age,
}
let man: Man.name = Player.name; // , Player.name Man.name
let player: Player.age = Man.age; // , Man.name Player.name
クラスクラスの基本比較
Type Scriptでは、例示的なメンバーと方法だけが比較され、静的なメンバーと構造関数は比較されない.
class Man {
name: string;
constructor(arg: string,) {
this.name = arg;
}
showName() {
return this.name;
}
}
class Player {
static age: number;
name: string;
constructor(arg: string, hero: boolean) {
this.name = arg;
}
showName() {
return this.name;
}
}
let man = new Man(" ");
let player = new Player(" ", true);
man = player;
player = man;
上記の例から、2つのクラスは異なる構造関数と静的構成員を持っているが、彼らは同じ実例的な構成員と方法を持っているので、彼らの間に互換性があることが分かる.クラスのプライベートメンバーと保護されたメンバー
クラスのプライベートメンバーと保護されたメンバーの互換性の比較規則は同じです.二つの種類を比較する時、二つの種類に分けて見ます.二つの種類は親子で、父類に私有メンバーがいる場合、二つの種類は互換性があります.2つのクラスが同じクラスのクラスであり、また、同じクラスにプライベートまたは保護されたメンバーが含まれている場合は、互換性がありません.次の二つの例を見てください.親子類:
class Man {
private name: string;
constructor(arg: string) {
this.name = arg;
}
}
class Player extends Man {
constructor(arg: string) {
super(arg);
}
}
let man = new Man(" ");
let player = new Player(" ");
//Man Player ,
man = player;
player = man;
クラス:class Man {
private name: string;
constructor(arg: string) {
this.name = arg;
}
}
class Player {
private name: string;
constructor(arg: string) {
this.name = arg;
}
}
let man = new Man(" ");
let player = new Player(" ");
man = player; // , Player Man, name
player = man; // , Man Player, name
汎型Type Script汎型の互換性は二つの場合に分けられます.一つはタイプパラメータがメンバーに使用されていません.もう一つは、タイプパラメータがメンバーによって使用されることである.まずタイプパラメータがメンバーに使用されていない場合を見ます.
interface IMan{
}
let man1: IMan;
let man2: IMan;
man1 = man2;
man2 = man1;
タイプパラメータがメンバーによって使用される場合:interface IMan{
name: T;
}
let man1: IMan;
let man2: IMan;
man1 = man2; // ,IMan IMan
man2 = man1; // ,IMan IMan
interface IMan{
name: T;
}
let man1: IMan;
let man2: IMan;
man1 = man2;
man2 = man1;
Type Scriptの汎型では、タイプパラメータがメンバーに使用されていない場合、互換性には影響がありません.パラメータがメンバーによって使用されると、互換性に影響します.参照
https://github.com/zhongsp/Ty... https://github.com/jkchao/typ...
最後に
文章の中には自分の理解を入れるところがあります.正確でないところや間違っているところがあれば、ご指摘ください.