function play(football) {
console.log('Playing: ${football}!'};
}
function palayOne(first: string, second: string) {
conssole.log('${first} / ${second});
palyOne("sport and soccer");
// Error: Exptected 2 arguments, but got 1.
playOne("team", "player"); // ok
playOne("team", "palyer", "ball");
// Error: Expected 2 arguments, but got 3.
}
function Play(football: string, palyer?: string) {
conosle.log('Play: ${football)');
if(palyer) {
console.log('Player ${player}');
}
}
Play("a"); // ok
Play("a", undefined); // ok
Play("a", "b"); // ok
function Play(football: string, player: string | undefined) {
Play("a");
// Error: Expected 2 arguments but got 1.
Play("a", undefined); // ok
Play("a", "b"); // ok
function Play(player?: string, football: string) {}
// Error: A required parmeter cannot follow an optional parameter.
function Play(football:string, score = 0) {
console.log('${football} gets ${score} / star!);
}
Play("a"); //ok
Play("a", 2); // ok
Play("a", undefined); // ok
Play("a", "7").
// Error : Argument of type "7" is not assignable to
// Parameter of type 'number | undefined'.
function allSongs(singer: string, ...songs: string[]) {
for (const song of songs) {
console.log('${song}, by ${singer}');
}
}
allSongs("a"); //ok
allSongs("a", "b", "c"); //ok
allSongs("a", 3000);
// Error : Argument of type 'number' is not assignable to parameter of type 'string'
function getSongs(s: string[], n: number) {
return n < s.length ? s[n]: undefined
}
변수와 마찬가지로 타입 애너테이션을 사용해 함수의 반환 타입을 명시적으로 선언하지 않는 것이 좋다.
함수에서 반환 타입을 명시적으로 선언하는 방식이 매우 유용할 때가 종종 있다.
- 가능한 반환값이 많은 함수가 항상 동일한 타입의 값을 반환하도록 강제한다.
- 타입스크립트는 재귀 함수의 반환 타입을 통해 타입을 유추하는 것을 거부한다.
- 수백 개의 이상의 타입스크립트 파일이 있는 매우 큰 프로젝트에서 타입스크립트 타입검사 속도를 높일 수 있다.
함수 선언 반환 타입 애너테이션은 매개변수 목록이 끝나는 ) 다음에 배치되고, 함수 선언의 경우는 { 앞에 위치한다.
function btsSong(songs: string[], count=0): number{
return songs.length ? btsSong(songs.slice(1), count+1) : count;
}
function btsSong = (songs: string[], count = 0): number =>
songs.length ? btsSong(songs.slice(1), count+1) : count;
function btsDebutDate(song: string):
Date | undefined {
swich (song) {
case "2cool4skool";
return new Date("June 13, 2013"); //ok
case "save me";
return "unkonwn";
// Error: Type 'string' is not assignable to type 'Date'
default:
return undefined; // ok
}
}
const nothing: () => string; // 매개변수가 없고 string 타입을 반환
const input:(songs: string[], count?: number) => number;
// string[]매개변수와 count 선택적 매개변수 및 number 값을 반환하는 함수를 설명
const songs = ['Juice", "Sake It Off", "what's up"];
function runSongs(getSongAt: (index: number) => string) {
for(let i = 0; i < songs.length; i += 1){
console.log(getSongsAt(i));
}
}
function getSongAt(index: number) {
return '${songs[index]}';
}
runOnSongs(getSongAt); // ok
function logSong(song: string) {
return '${song}';
}
runOnSongs(logSong);
//Error: Argument of type '(song: string) => string' is not
// assignable to parameter of type '(index: number) => string'.
// Type of parameters 'song' and 'index' are incompatible.
// Type 'number' is not assignable to type 'string'
runOnSong
에 대한 오류 메시지// 타입은 string | undefined 유니언을 변환하는 함수
let returnString:() => string | undefined;
// 타입은 undefined 나 string 을 반환하는 함수
let myReturn: (() => string) | undefined;
let singer: (songs: string) => string;
singer = function (song) {
// song: string 타입
return 'Singing: ${song.toUpperCase()}!'} // ok
const songs = ["a", "b", "c];
// song: string
// index: number
songs.forEach((song, index) => {
console.log('${song} is at index ${index}')
});
type StringNumber = (input: string) => number;
let stringNumber: StringNumber;
stringNumebr = (input) => input.length; //ok
stringNumber = (input) => input.toUpperCase();
//Error: Type 'string' is not assignable to type 'number'
type NumberString = (input: number) => string;
function useSNumberString(numberString: NumberString) {
console.log('The string is: ${numberString(1234)}');
}
usesMunberString((input) => '${input}! Hooray!'); // ok
usesNumberString((input) => input * 2);
// Error: Type 'number' is not assignable to type 'string'
0️⃣ void 반환 타입
funtion logSong (song: string | undefined): void {
if (!song) {
return; // ok
}
console.log('${song});
return true;
// Error : Type 'boolean' is not assignable to type 'void'
let songLogger: (song: string) => void;
songLogger = (song) => {
console.log('${songs}');
};
songLogger("Fake Love"); // ok
function returnVoid() {
return;
}
let lazyValue: string | undefined;
lazyValue = returnVoid();
// Error : Type 'void' is not assignable to type 'string| undefined'.
const records: string[] = [];
function saveRecords(newRecords: string[]) {
newRecords.forEach(record => records.push(record));
}
saveRecords(['22', 'yet to come', 'permission to Dance'])
function fail(message: string): never {
throw new Error ('Invariant failure: ${message}.');
}
function workWithUnsafeParam(param:unknown) {
if(typeof param !== 'string') {
fail('param should be a string, not ${typof param}');
}
param.toUpperCase(); // ok
}
function createDate(timestamp: number): Date;
function createDate(month: number, day: number, year: number): Date;
function createDate(monthOrTimestamp: number, day?:number, year?: number) {
return day. === undefined || year === undefined
? new Date(monthOrTimestamp)
: new Date (year, monthOrTimestamp, day);
}
createDate(1231); // ok
createDate(2, 22, 2222); // ok
createDate(4, 1);
// Error : No overload expects 2 arguments, but overloads
// do exist that expect eithor 1 or 3 arguments.
함수의 오버로드 시그니처에 있는 반환 타입과 각 매개변수는 구현 시그니처에 있는 동일한 인덱스이 매개변수에 할당할 수 있어야 한다. (구현 시그니처는 모든 오버로드 시그니처와 호환되어야 함)
function format(data: string): string; // ok
function format(data: string, needle: string, haystack: string): string; // ok
function format(getData: () => string): string;
// Error: This overload signature is not compatible with its implementation signature
function format (data: string, neele? string, haystack? string) {
return needle && haystack ? data. replace(needle, haystack) : data;
}
[Reference]
1. Learning typeScript(조시 골드버그/고승원/한빛미디어_2023)