Rest parameter
rest parameter는 항상 [ ] 안에 담겨오기 때문에 타입지정도 array처럼 해준다.
function Plus(...a: number[]) {
console.log(a);
}
Plus(1, 2, 3, 4, 5);
Destructuring
1. parameter에 object처럼 타입지정.
2. type 키워드로 따로 만들어서 지정.
// Object
let person = { student: true, age: 20 };
// 파라미터에 object처럼 타입지정
function 함수({ student, age }: { student: boolean; age: number }) {
console.log(student, age);
}
함수({ student: true, age: 20 });
// 2. type 키워드
type obj5 = {
student: boolean;
age: number;
};
// Array
type Check2 = (number | string | boolean)[];
function 연습2([a, b, c]: Check2) {
console.log(a, b, c);
}
연습2([40, "wine", true]);
Private / Protected
class안에서 public 키워드 사용하면 그 속성은 아무데서나 수정 가능하다.
( 필드값 같은걸 그냥 만들면 public이 몰래 왼쪽에 부여되므로 붙이든 안붙이든 사실 똑같..)
* public 키워드는 class내의 prototype 함수에도 붙일 수 있다.
🔻 private 키워드 붙이면 무조건 class { } 중괄호 안에서만 수정 및 사용이 가능하다.
( class로 부터 생성된 자식 object 에서도 사용 불가능 )
외부에서 실수로 수정하지 않도록 지켜주고싶은 중요한 변수나 속성에 안전장치로 private 붙여준다.
> class 밖에서 죽어도 수정하고 싶으면?
private 속성을 수정하는 함수를 class안에 만들어서 함수를 실행한다.
class User {
public name :string;
private familyName :string;
constructor(){
this.name = 'kim';
let hello = this.familyName;
}
changeSecret(){
this.familyName = 'park';
}
}
let 유저1 = new User();
유저1.familyName = 'park'; //에러남
유저1.changeSecret() //가능
🔻 Protected : private인데 약간 보안을 해제하고 싶을 때
1. private랑 같은데
2. extends 된 class 안에서도 사용가능하다. (Userd의 자식은 사용 불가능. extends된것만!!)
class User {
protected x = 10;
}
class newUser extends User {
changeNum() {
this.x = 20;
}
}
Static
class { }안에 들어가는 변수, 함수 등은 (필드값은 ) 전부 instance에 부여된다.
이걸 바꿔서 class에 직접 변수나 함수를 부여하고 싶을 때 static 키워드를 붙여준다.
🤷🏻♀️ 언제씀?
: 주로 class안에 간단한 메모를 하거나, 기본 설정값 입력
instance에서 사용할 필요가 없는 변수들을 만들어놓고 싶을 때 사용한다.
class User1 {
x = 10;
}
let user1 = new User1();
User1.x; //불가능
user1.x //가능
class User1 {
static x = 10;
}
let user1 = new User1();
User1.x; //가능
user1.x //불가능
private, protected, public과 함께 사용가능하다.
class User4 {
//필드값은 모든 User4의 자식에게 물려주는 속성이지만, static 붙은 x,y는 자식들은 쓸수없다.
//User4.x 이런식으로만 접근가능하다.
private static x = 10;
//x는 class내부에서만 수정가능하다.
public static y = 20;
//y는 내외부 상관없이 수정가능하다.
}
Import
타입변수도 ES6 import export 문법 그대로 사용해서 다른파일에서 사용 가능하다.
(a.ts)
export type Name = string | boolean;
export type Age = (a :number) => number;
(b.ts)
import {Name, Age} from './a'
let 이름 :Name = 'kim';
let 함수 :Age = (a) => { return a + 10 }
(참고) namespace
: 이전엔 중요한 타입정의들을 다른 파일들에서 쓰고 싶으면 안전하게 namespace 안에 써서 export 해줬다.
(a.ts)
namespace MyNamespace {
export interface PersonInterface { age : number };
export type NameType = number | string;
}
(b.ts)
/// <reference path="./a.ts" />
let 이름 :MyNamespace.NameType = '민수';
let 나이 :MyNamespace.PersonInterface = { age : 10 };
type NameType = boolean; //사용 가능
interface PersonInterface {} //사용 가능
그러면 ts 파일은 <reference/> 라는 태그를 이용해서 다른 파일을 import해올 수 있는데
그럼 이제 그 파일에 있던 namespace를 사용가능하다.
네임스페이스명.타입명
이렇게 쓰면 다른 파일에 있던 타입변수를 자유롭게 쓸 수 있다.
Generic
[서론]
타입스크립트는 타입을 알아서 변경해주지 않는다.
(숫자가 return되면 'number 타입임다!' 이런거 안됨)
function 함수3(x: unknown[]) {
return x[0];
}
let a = 함수3([4, 2, 3]);
console.log(a+1); //에러
그래서 이런경우도 에러가 발생한다.
a는 type지정이 안됬으므로, unknown타입이고 그래서 a+1같은 연산도 에러가 발생한다.
불확실한 unknown, any, union 타입을 입력하면 나오는 값도 동일하고 이때문에 에러가 발생한다.
해결은 narrowing을 하면되는데 구찮,,
이럴 때 generic을 사용한다.
🔻 Generic : 타입파라미터 문법
애초에 타입을 파라미터로 함수에 미리 입력한다.
그러면 원하는 곳에 가변적으로 타입지정이 가능하다.
유연성과 타입의 안전성을 동시에 지킬 수 있다.
function 함수3<T>(x: T[]): T {
return x[0];
}
let a = 함수3<number>([4, 2, 3]);
//function 함수3 (x: number[]): number {
// return x[0];
//}
let b = 함수3<string>(["kim", "park"]);
함수에 <> 이런 괄호에 파라미터를 또 입력할 수 있는데, 여기안엔 타입만 입력할 수 있다. (타입 파라미터 문법)
a에는 <number>를 입력했으므로 function 함수3 (x : number[]):number { } 와 같다.
✔️ <T>에 number말고 다른것도 들어갈 수 있기때문에 연산에서는 에러가 발생.
function 함수3<T>(x: T[]): T {
return x - 1; //에러
}
let a = 함수3<number>([4, 2, 3]);
해결 ) narrowing하거나 <T>에 넣을 수 있는 타입 미리 제한한다. (constraints : extends 사용)
function 함수3<T extends number>(x: T) {
return x - 1;
}
let a = 함수3<number>(100);
* interface로 커스텀한 타입도 extends 가능
interface lengthCheck {
length: number;
}
function 함수4<MyType extends lengthCheck>(x: MyType) {
return x.length;
}
let c = 함수4<string>("hello");
* class에서 Generic사용
class Person3<T> {
name;
constructor(a2: T) {
this.name = a2;
}
}
let a2 = new Person3<string>("어쩌구");
console.log(a2.name);
'Archive' 카테고리의 다른 글
[GIT] Github 잔디 안심어지는 현상 (0) | 2022.01.05 |
---|---|
[JS] getter,setter / import,export (0) | 2022.01.05 |
[TS] instanceof / Class types / Interface (0) | 2022.01.01 |
[TS] Type Aliases / Literal Type (0) | 2021.12.30 |
[JS] 객체지향 2 ( Create, Class ) (0) | 2021.12.28 |