エレガントなタイプのスクリプトの概要
65376 ワード
🤔 タイプスクリプトの使用方法
1.作成者とユーザー
タイプシステム
タイプスクリプトのタイプシステム
タイプを明確に指定できます.
タイプが明示的に指定されていない場合、タイプスクリプトコンパイラは自動的にタイプを推定します.
タイプは変数が何ができるかを決定します.
関数の使い方を誤解するJavaScript
// JavaScript
// f2 실행의 결과가 NaN을 의도한 것이 아니라면
// 이 함수의 작성자는 매개변수 a 가 number 타입이라는 가정으로 함수를 작성했습니다.
function f2(a) {
return a;
}
// 사용자는 사용법을 숙지하지 않은 채, 문자열을 사용하여 함수를 실행했습니다.
console.log(f2(10)); // 380
console.log(f2('Mark')); // NaN
noImplicitAny 옵션
タイプが明確に指定されていない場合、タイプスクリプトが推定時にanyと判断すると、コンパイルエラーが発生し、タイプを明確に指定するように起動します.
strictNullChecks 옵션
すべてのタイプに自動的に含まれるnullとundefinedを削除します.noImplicitReturns 옵션
関数内のすべてのコードが値を返さない場合、コンパイルエラーが発生します.object literal type
function f7(a:{name:string; age: number}):string {
return `이름은 ${a.name}이고 연령대는 ${Math.floor(a.age/10) * 10}대 입니다.`;
}
console.log(f7({name:'Mark',age:38})); // 이름은 Mark이고, 연령대는 30대 입니다.
console.log(f7('Mark')); // error TS2345: Argument of type 'string' is not assignable to parameter of type '{name:string; age:number;}'.
2.インタフェースとタイプ別名
構造タイプsystem-構造が同じ場合は同じタイプ
interface IPerson{
name: string;
age: number;
speak(): string;
}
type PersonType = {
name: string;
age: number;
speak(): string;
};
let personInterface: IPerson = {} as any;
let personType: PersonType = {} as any;
personInterface = personType;
personType = personInterface;
nominaltype system-構造は同じですが名前が異なるタイプ
type PersonID = string & { readonly brand: unique symbol};
function PersonID(id:string):PersonID{
return id as PersonID;
}
function getPersonById(id:PersonID){}
getPersonById(PersonID('id-aaaaaa'));
getPersonById('id-aaaaaa'); // error TS2345: Argument of type 'string' is not assignable to
// parameter of type 'PersonID'. Type 'string' is not assignable to type '{readonly brand:unique symbol;}'.
Function
// type alias
type EatType = (food:string) => void;
// interface
interface IEat {
(food:string): void;
}
Array
// type alias
type PersonList = string[];
// interface
interface IPersonList{
[index:number]:string;
}
Intersection
interface ErrorHandling {
success:boolean;
error?:{ message: string };
}
interface ArtistsData {
artists: { name: string }[];
}
// type alias
type ArtistsResponseType = Artists & ErrorHandling {}
// interface
interface IArtistsResponse extends ArtistsData, ErrorHandling{}
let art : ArtistsResponseType;
let iar : IArtistsResponse;
Union Types
interface Bird {
fly(): void;
layEggs(): void;
}
interface Fish {
swim(): void;
layEggs():void;
}
type PetType = Bird | Fish;
interface IPet extends PetType {} // error TS2312: An interface can only extend an object type or
//intersection of object types with statically known members;
class Pet implements PetType {} // error TS2422: A class can only implement an object type or
//intersection of object types with statically known members
Declation Merging - interface
interface MergingInterface {
a: string;
}
interface MergingInterface {
b: string;
}
let mi: MergingInterface = { a: 'hello', b: 'world' };
他のモジュール/ライブラリタイプを拡張する場合はglobalを選択します.d.ts作成後のネームスペースでの使用[delay type aliasとinterfaceはいつ使いますか?]
3.サブタイプとスーパータイプ
Case 1
let sub1: 1 = 1;
let sup1: number = sub1;
sub1 = sup1; // error Type 'number' is not assignable to type '1';
let sub2: number[] = [1];
let sup2: object = sub2;
sub2 = sup2; // error Type 'number[]' is not assignable to type '{number,number}'
let sub3: [number,number] = [1,2];
let sup3: number[] = sub3;
sub3 = sup3; // error Type 'number[]' is not assignable to type '[number,number]'.
// Target requires 2 element(s) but source may have lower.
Case 2
let sub4: number = 1;
let sup4: any = sub4;
sub4 = sup4;
let sub5: never = 0 as never;
let sup5: number = sub5;
sub5 = sup5; // error Type 'number' is not assignable to type 'never'
class SubAnimal {}
class SubDog extends SubAnimal{
eat(){}
}
let sub6: SubDog = new SubDog();
let sup6: SubAnimal = sub6;
sub6 = sup6; // error Property 'eat' is missing type 'SubAnimal' but required in type 'SubDog'.
≪共通関係|Common Relationships|emdw≫:同じタイプまたはサブタイプの場合、割当てできます。
// primitive type
let sub7: string = '';
let sup7: string | number = sub7;
// object - 각각의 프로퍼티가 대응하는 프로퍼티와 같거나 서브타입이어야 한다.
let sub8 : { a: string; b: number } = { a: '', b: 1 };
let sup8 : { a: string | number; b : number } = sub8;
// array - object와 마찬가지
let sub9 : Array<{ a: string; b: number }> = [{a: '', b: 1 }];
let sup9 : Array<{ a: string | number ; b: number }> = sub9;
ハーフボトル:関数のパラメータタイプが同じかスーパータイプの場合、割り当てることができます。
class Person {}
class Developer extends Person {
coding() {}
}
class StartupDeveloper extends Developer{
burning() {}
}
function tellme(f: (d: Developer)=> Developer) {}
// Developer 에다가 Developer 할당하는 경우
tellme(function dToD(d:Devleopr):Developer {
return new Developer();
});
// Developer 에다가 Person 할당하는 경우
tellme(function pToD(d:Person):Developer{
return new Developer();
});
// Developer 에다가 StartupDeveloper 할당하는 경우 (타입에러는 나지 않지만 기대하는 결과X)
tellme(function sToD(d:StartupDeveloper):Developer {
return new Developer();
});
strictFunctionTypes 옵션
関数のパラメータタイプが同じかスーパータイプでない場合は、エラーによって警告されます.unknown代替
// 입력은 마음대로,
// 함수 구현은 문제 없도록
function funknown(a: unknown): number | string | void {
a.toString(); // error! Object is of type 'unknown'
// 명확하게 타입별로 처리하도록 유도
if(typeof a === 'number'){
return a * 38;
}else if(typeof a === 'string'){
return `Hello ${a}`;
}
}
4.理解型推論
let a = 'Mark'; // string
const b = 'Mark'; // 'Mark' => literal type
let c = 38; // number
const d = 38; // 38 => literal type
let e = false; // boolean
const f = false; // false => literal type
let g = ['Mark', 'Haeun']; // string[]
const h = ['Mark','Haeun']; // string[]
const f = ['Mark','Haeun'] as const; // readonly ['Mark','Haeun']
Best common type
let j = [0,1,null]; // (number|null)[]
const k = [0,1,null]; // (number|null)[]
class Animal{}
class Rhino extends Animal{}
class Elephant extends Animal{}
class Snake extends Animal{}
let i = [new Rhino(),new Elephant(),new Snake()]; // (Rhino | Elephant|Snake)
const m = [new Rhino(),new Elephant(),new Snake()]; // (Rhino | Elephant|Snake)
const n = [new Animal(),new Rhino(),new Elephant(),new Snake()]; // Animal[]
const o: Animal[] = [new Rhino(),new Elephant(),new Snake()]; // Animal[]
Context Type-位置による推定
// Parameter 'e' implicitly has an 'any' type.
const click = (e) => {
e; // any
};
document.addEventListener('click',click);
document.addEventListener('click',(e)=>{
e; // MouseEvent
});
5.タイプGuardを使用してセキュリティを決定
Type of Type Guard-通常はPrimitiveタイプ
function getNumber(value: number | string):number{
value; // number | string
if(typeof value === 'number'){
value; // number
return value;
}
value; // string
return -1;
}
instanceof Type Guard
interface IMachine {
name: string;
}
class Car implements IMachine {
name: string;
wheel: number;
}
class Boar implements IMachine {
name: string;
motor: number;
}
function getWhellOrMotor(machine: Car | Boat): number{
if(machine instanceof Car){
return machine.wheel; // Car
}else {
return machine.motor; // Boat
}
}
Instanceof Type Guard-Errorは、オブジェクトの区別によく使用されます。
class NegativeNumberError extends Error {}
function getNumber(value: number): number | NegativeNumberError {
if(value < 0) return new NegativeNumberError();
return value;
}
function main(){
const num = getNumber(-10);
if(num instanceof NegativeNumberError){
return;
}
num; // number
}
処理in operatorタイプGuard-objectのproperty有無
interface Admin {
id: string;
role: string;
}
interface User {
id: string;
email: string;
}
function redirect(user: Admin | User) {
if("role" in user){
routeToAdminPage(user.role);
}else{
routeToHomePate(user.email);
}
}
literal Type Guard-objectのプロパティは同じで、タイプが違います
interface IMachine {
type: string;
}
class Car implements IMachine {
type: 'CAR';
wheel: number;
}
class Boat implements IMachine {
type: 'BOAT';
motor: number;
}
function getWheelorMotor(machine: Car | Boat): number {
if(machine.type === 'CAR'){
return machine.wheel;
}else {
return machine.motor;
}
}
custom Type Guard
function getWheelOrMotor(machine:any):number{
if(isCar(machine)){
return machine.wheel;
}else if(isBoat(machine)){
return machine.motor;
}else{
return -1;
}
}
function isCar(arg:any):arg is Car {
return arg.type === 'CAR';
}
function isBoat(arg:any):arg is Boat {
return arg.type === 'BOAT';
}
6.安全にクラスを作成する
カテゴリ属性のタイプを明確に指定する必要があります
class Square {
area: number;
sideLength: number;
}
const square = new Square();
console.log(square.area); // compile time - number, runtime - undefined
console.log(square.sideLength); // complie time - number, runtime - undefined
strictPropertyInitialization 옵션
classのpropertyがジェネレータまたは宣言に値を指定していない場合、コンパイルエラーが発生し、注意を喚起します.宣言でClass Propertyを初期化
class Square {
area: number = 0;
sideLength: number = 0;
}
クラスプロパティジェネレータで初期化
class Square {
area: number;
sideLength: number;
constructor(sideLength: number){
this.sideLength = sideLength;
this.area = sideLength ** 2;
}
}
クラス属性のタイプ推論
// 생성자에 의해 property 타입이 추론됨
class Square {
area;
sideLength;
constructor(sideLength: number){
this.sideLength = sideLength;
this.area = sideLength ** 2;
}
}
まだ生成者を離れては推論できないclass Square {
sideLength!: number; // !로 의도를 표현해야 한다.
constructor(sideLength: number){
this.initialize(sideLength);
}
initialize(sideLength: number){
this.sideLength = sideLength;
}
get area(){
return this.sideLength ** 2;
}
}
Reference
この問題について(エレガントなタイプのスクリプトの概要), 我々は、より多くの情報をここで見つけました https://velog.io/@dodose/우아한-타입스크립트-요약-정리テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol