Call Signatures은 함수의 인수 유형 및 반환 유형입니다.
const add = (a: number, b: number) => a + b; //권장X
type Add = (a: number, b: number) => number; //Call Signatures
//아래와 같이도 Call Signatures를 사용할 수 있다.
//type Add = (a : number, b : number) : number
const plus: Add = (a, b) => a + b;
❗️중괄호를 만들어 주게 되면 에러가 발생한다.
위에 코드는 void 값을 가질 수 없다는 에러 메시지이다.
위 코드를 일반 함수로 풀게 된다면 아래 코드와 같다.
function add(a, b){
a + b
}
즉, arrow function에서 {}를 사용하게 되면 그 안의 값은 반환이 아니라 함수 내부 내용으로 처리 되기에 반환값이 없는 void로 처리된다.
함수가 여러개의 call Signatures를 가지고 있을 때 발생시킨다.(서로 다른 call Signature)
type Add = {
(a: number, b: number): number;
(a: number, b: string): number;
};
const add: Add = (a, b) => {
if (typeof b === "string") return a;
return a + b;
};
나쁜예시: 이건 매우 매우 소수의 함수만 이런식으로 할 수 있다.
권장 방법
type Config = {
path: string;
state: object;
};
type Push = {
(path: string): void;
(config: Config): void;
};
const push: Push = (config) => {
if (typeof config === "string") {
console.log(config);
} else {
console.log(config.path);
}
};
push("real");
if) 하나의 call Signature는 두개의 파라미터를 가지고 다른 하나는 3개의 파라미터를 가지는 경우
에러발생 다른 개수의 파라미터를 가지기 때문이다.
해결방법
type Add = {
(a: number, b: number): number;
(a: number, b: number, c: number): number;
};
const add: Add = (a, b, c?: number) => {
if (c) return a + b + c;
return a + b;
};
console.log(add(1, 2)); //3
console.log(add(1, 2, 3)); //6
void
실수로 뭔가 return하는걸 사전에 막을 수 있다.
ex1)정상 작동
function 함수(x : number) :void{
1+1
}
ex2)에러 발생
에러메시지 : `Type 'number' is not assignable to type 'void'.
숫자타입은 void타입에다가 넣을 수 없다는 뜻이다.
함수 쓰고 뱉고 싶지 않을 때 쓰면 된다.
타입스크립트를 사용하게 되면 파라미터는 필수이다.
ex)
파라미터 무조건 써야된다.
?
는 변수가 들어올 수 도 있고 안들어 올 수도 있다는 뜻이긴 하지만 정확히는
변수 : number | undefined
와 같다.
ex) ?
기능을 사용하면 에러가 발생하지 않는다.
function 함수(x ?: number) :void{
}
함수()
function myFn(x : number | string){
let array : number[] = [];
if(typeof x === 'number'){
array[0] = x;
}
}
myFn(123);
함수 안에서 if문 쓸 때는 마지막에
else{}
가 없으면 에러가 난다.
return 하지 않는 조건문이 있다면 나중에 버그가 생길 수 있어서 에러를 내주는 것이다.
해결 방법
"nolmplicitReturns":false
를 tsconfig.js에 추가 해준다. 하지만, 이렇게 해결하는 것보단 엄격하게 코드를 작성하는게 좋다.
❗️꼭 typeof
를 사용하지 않고 in
, instanceof
키워드도 사용가능하다.
(숙제1) 이름을 파라미터로 입력하면 콘솔창에 "안녕하세요 홍길동"을 출력해주고
아무것도 파라미터로 입력하지 않고 함수를 사용하면 "이름이 없습니다" 를 출력하는 함수를 만들어봅시다.
파라미터와 return 타입지정도 잘 해봅시다.
어떻게 했나
function sayHi(x? :string ){
if (x) {
console.log('안녕하세요 ' + x)
} else {
console.log('왜입력안함')
}
}
별거 아니라 설명은 생략합니다
return이 없어야한다면 return 타입도 void로 설정해보는게 어떨까요.
(숙제2) 함수에 숫자 또는 문자를 집어넣으면 자릿수를 세어 출력해주는 함수를 만들어보십시오.
예를 들어 '245' 이런 문자를 입력하면 3이 return 되어야합니다.
숫자도 마찬가지로 9567 이런 숫자를 입력하면 4가 return 되어야합니다.
숫자 또는 문자 이외의 자료가 들어오면 안됩니다.
글자 자릿수세는 방법은 찾아보셈
function 자릿수세기(x :number | string) :number {
return x.toString().length
}
구글에 물어보니 문자에 .length 붙이면 자릿수 세준다고 하네요.
근데 숫자는 .length를 붙여줄 수 없으니까
우선 문자로 변환했다고 합니다.
변환하는 함수도 역시 구글에 물어보니 .toString() 쓰면 된다고 하는군요.
물론 더 정확하게 하려면
만약에 x가 숫자일 경우 이렇게,
문자일 경우 이렇게 하라고 코드짜는게 좋습니다.
(숙제3) 결혼 가능 확률을 알려주는 함수를 만들어봅시다.
함수의 파라미터로 월소득(만원단위), 집보유여부(true/false), 매력점수 ('상' or '중' or '하') 를 입력할 수 있어야합니다.
월소득은 만원 당 1점, 집보유시 500점 & 미보유시 0점, 매력점수는 '상'일 때만 100점으로 계산합니다.
총 점수가 600점 이상일 경우 "결혼가능"을 return 해줘야합니다. 그 외엔 아무것도 return하지 않습니다.
(예시)
결혼가능하냐(700, false, '중') 이렇게 사용할 경우 "결혼가능"을 return 해줍니다.
결혼가능하냐(100, false, '상') 이렇게 사용할 경우 아무것도 return되지 않습니다.
해보고 눌러봅시다
function 결혼가능하냐(money :number, house :boolean, charm :string) :string|void{
let score :number = 0;
score += money;
if (house === true){
score += 500
}
if (charm === '상'){
score += 100
}
if (score >= 600){
return '결혼가능'
}
}
console.log(결혼가능하냐(100,true,'상'))
score라는 변수를 만들고
차례로 money에 따라 score를 + 시켰고
house여부에 따라 score를 + 시켰고.. 그랬다고 합니다.
콘솔창에 출력해보니 집있고 매력있는 사람은 월 소득에 관계없이 항상 결혼이 가능하군요.
하지만 월 소득을 마이너스로 이상한 숫자를 입력하면 어쩌죠?
그런 것도 막으려면 코드를 어떻게 짜야할까요.
마지막으로 string이 아니라 '상' '중' '하' 라는 글자만 입력할 수 있게 더욱 엄격한 타입지정도 가능한데
그건 Literal type 시간에 알아봅시다.
변수명 as string
"이 변수를 string라고 주장하겠습니다."라는 뜻이다.
as키워드를 사용하면 된다.
as
1.as
키워드는 union type 같은 복잡한 타입을 하나의 정확한 타입으로 줄이는 역할을 수행한다. 하지만,number
타입을as string
으로 변경하려고 하면 에러가 발생한다. 왜나하면 실은as
는 그냥 타입실드 임시해제용이다. 실제 코드 실행결과는as
가 있을 때나 없을 때나 거의 동일하다.
즉,as
는 그냥 주장만 하는거지 실제로 타입을 바꿔주는 기능을 하지 못한다.
ex1)
function assertionFn(x : number | string){
let array : number[] = []
//array[0] =x;
//위에 있는 코드사용시 TS error 가 발생한다. → number타입만 들어올 수 있다.
array[0] = x as number;
//왼쪽에 있는 변수를 넘버로 덮어 써달라는 문법이다.
//타입스크립트 컴파일러는 x는 number구나 하고 넘어가게 된다.
}
assertionFn(123)
❗️주의할 점
타입을 a에서 b로 변경 하는 문법이 아니다.
에러 발생
❗️주의할 점2
function asserFn(x : nubmer | string){
let array : number[] = [];
array[0] = x as number;
}
asserFn('123')
문자를 넣어도 아무일도 발생하지 않는다.
즉, assertion 해놓으면 이런 버그를 캐치하지 못하게 된다.
결론
- if문으로 narrowing 하는거 선호
- 남이 짠 코드를 수정할 때 왜 타입에러가 나느지 모르겠을 때 비사용으로나 사용하기
결론 : 특정 글자나 숫자만 가질 수 있게 제한을 두는 타입을 literal type이라고 부른다.
let 이름 : string;
let name : 123;
name = 456;//error 발생
//이 변수엔 무조건 123만 들어올 수 있다.
let 접니다 : '대머리' | '솔로';
접니다 = '대머리' //대머리 또는 솔로가 들어온다.
type game = '가위'|'바위'|'보'
function 함수( a : game) : game[]{
return ['가위']
}
함수('가위')
const 변수와 유사하게 사용 가능
let 접니다 : '대머리' | '솔로';
//이런 식의 문법은 자바스크립트에 없다.
const 변수 = 'kim';
Literal type은 const 변수 업글 버전이다.
var 자료 = {
name : 'kim'
}
function 내함수(a : 'kim'){
}
내함수(자료.name) //error 발생
에러 원인
내함수 함수의 파라미터a : 'kim
은 'kim'이라는 자료만 들어올 수 있다가 아니다. 'kim'이라는 타입만 들어올 수 있다는 것이다.
해결방법
1. object 만들 때 타입지정 확실히 하기
2. as문법으로 타입을 구라칠 수 있음
3. as const 쓰면 된다.
as const
사용
var 자료 = {
name : 'kim'
} as const
function 내함수(a : 'kim'){
}
내함수(자료.name)
as const는 이 object는 literal type처럼 해달라는 뜻이다.
as const는 object 속성들에 모두 readonly를 붙여준다.
object 자료를 완전히 잠가놓고 싶으면 as const를 사용하면 된다.
ex)
type NumOut = (x : number, y: number) => number
let ABC : NumOut = function(x,y){
return x + y
}
ex)
type member = {
name : string,
age : number,
plusOne : (x:number) => number,
changeName : ()=> void
}
let 회원정보 : member = {
name : 'kim',
age : 30,
plusOne(x){
return x + 1
},
changeName : ()=>{
console.log('안녕')
}
}
회원정보.plusOne(1);
회원정보.changeName();
🌈 참고 : 한 줄 끝나면 콤마대신 세미콜론도 가능
기본활용 예제)
interface Square{
color : string
width : 100
}
let 네모:Square = { color : 'red', width : 100 }
Student interface & Teacher interface가 필요하다고 가정
중복이 발생된 예제)
interface Student{
name : string
}
interface Teacher {
name : string,
age : number
}
중복사항을 해결하려면 extends 문법을 사용하면 된다.
interface Student{
name : string
}
interface Teacher extends Student {
age : number
}
Student interface를 extends 해달라고 적으면 Student 안에 있던걸 복사해서 Teacher에 넣어준다.