ch5. 함수
ch6. 배열
ch7. 인터페이스
ch8. 클래스
ch9. 타입제한자
ch10. 제네릭
함수 매개변수
//1.
const sing = (song) => {
console.log('Singing: ${song}!');
};
- sing함수는 song매개변수를 받아 콘솔에 출력한다.
- sing함수를 작성한 개발자가 song 매개변수를 제공하기 위해 의도한 값의 타입은 무엇?
- string인가? 재정의된 toString() 메서드가 있는 객체인가? 이 코드는 버그인가???
- 명시적 타입 정보가 선언되지 않으면 절대 타입을 알 수 없다.
- 타입스크립트가 이를 any타입으로 간주하며 매개변수의 타입은 무엇이든 될 수 있다.
//2.
const sing = (song: string) => {
console.log('Singing: ${song}!');
};
- 변수와 마찬가지로 타입스크립트를 사용하면 타입 애너테이션으로 함수 매개변수의 타입을 선언할 수 있다.
- 코드를 유효한 타입스크립트 구문으로 만들기 위해 함수 매개변수에 적절한 타입애너테이션을 추가할 필요는 없다.
- 타입스크립트는 타입 오류로 오류를 계속 알리지만, 이미 시작 된 자바스크립트는 계속 실행 됨.
- song 매개변수에 타입 선언이 누락된 코드 스니펫은 여전히 타입스크립트에서 자바스크립트로 변환 된다.
필수 매개변수
//1.
const singTwo = (first: string, second: string) => {
console.log('${first} / ${second}');
};
singTwo("Ball and Chain");
// log: "Ball and Chain / undefined"
// Error: Expected 2 arguments, but got 1.
singTwo("I will Servive", "Higher Love");
// log: "I will Servive", "Higher Love"
singTwo("Go your own way", "The Chain", "Dreams");
// log: "Go your own way / The Chain"
// Error: Expected 2 arguments, but got 3.
- 함수에 필수 매개변수 required Parameter를 제공하도록 강제하면, 예상되는 모든 이수값을 함수 내에 존재하도록 만들어 타입안정성을 강화하는데 도움이 된다.
- 모든 인수값이 존재하는지 확인하지 못하면 이전 singTwo함수가 undefined 를 로그로 남기거나 인수를 무시하는 것과 같이 코드에서 예기치 않은 동작이 발생한다.
- 매개변수는 인수로 받을 것으로 예상되는 함수의 선언을 나타낸다.
- 인수는 함수를 호출할 때 매개변수에 제공되는 값을 나타낸다.
const singTwo = (first: string, second: string) => {
// first와 second : 매개변수
console.log('${first} / ${second}');
};
singTwo("Go your own way", "The Chain", "Dreams");
// "Dreams"와 같은 문자열은 : 인수
선택적매개변수
//1.
const announceSong = (song: string, singer?: string) => {
console.log('Song: ${song}');
if (singer) {
console.log('Song: ${song}')
}
};
announceSong('Greensleeves');
announceSong('Greensleeves', undefined);
announceSong('Chandelier', 'Sia');
- announceSong함수에서 singer매개변수는 선택사항으로 표시된다.
- 타입은, string | undefined 이며 함수 호출자가 singer 매개변수를 위한 인수를 제공할 필요가 없다.
- 만일, singer가 제공되면 string 값이거나 undefined일 수 있다.
- 이러한 선택적 매개변수는 항상 암묵적으로 undefined 가 될 수 있음.
- singer는 string | undefined 타입으로 시작한 후 if 문에 따라 string타입으로 좁혀짐.
- 선택적 매개변수는, | undefined 를 포함하는 유니언 타입 매개변수와는 다름.
- ? 으로 표시된 선택적 매개변수가 아닌 매개변수가 아닌 매개변수는 값이 명시적으로 undefined 라도 항상 제공되어야 함.
//2.
const announceSongBy = (song: string, singer: string|undefined) => {
/* ... */
};
announceSongBy('Greensleeves');
// Error: Expected 2 arguments, but got 1.
announceSongBy('Greensleeves', undefined);
announceSong('Chandelier', 'Sia');
- announceSongBy 함수의 singer 매개변수는 명시적으로 제공되어야 한다.
- singer는 string 값이거나 undefined가 될 수 있다.
- 함수에서 사용되는 모든 선택적 매개변수는 마지막 매개변수여야 한다.
- `필수 매개변수 전에 선택적 매개변수를` 위치시키면 타입스ㅡ구문오류 발생
const announceSinger = (singer?: string, song: string) => {};
// Error: A required parameter cannot follow an optional parameter
기본매개변수
//1.
const rateSong = (song: string, rating = 0) => {
console.log('${song} gets ${rating}/5 stars!');
}
rateSong('Photograph');
rateSong('Set Fire to the Rain', 5);
rateSong('Set Fire to the Rain', undefined);
rateSong('At Last!', "100");
// Error: Argument of type '"100"' is mot assignable to paraeter of type 'number | undefined'
- rateSong 함수에서 rating은 number 타입으로 유추되지만, 함수를 호출하는 코드에서는 선택적 number | undefined 가 된다.
나머지매개변수
//1.
const singAllTheSongs = (singer: string, ...songs: string[]) => {
for (const song of songs) {
console.log('${song}, by ${singer}')
}
};
singAllTheSongs('Alicia Keys');
singAllTheSongs('lady gaga', 'just Dance', 'poker face');
singAllTheSongs('Ella Fitzgerald', 2000);
// Error: Argument of type 'number' is not assignable to parameter of type 'string';
- singAllTheSongs 은 songs 나머지 매개변수에 대해 0개 이상의 string 타입 인수를 사용할 수 있다.
반환타입
//1.
//타입: (song: string[]) => number
const singSongs = (songs: string[]) => {
for (const song of songs) {
console.log('${song}');
}
return (
songs.length;
)
}
- 함수에 다른 값을 가진 여러개의 반환문을 포함하고 있다면, 타입스크립트는 반환타입을 가능한 모든 반환타입의 조합으로 유추한다.
//2.
//타입: (songs: string[], index: number) => string | undefined
const getSongAt = (songsL string[], index: number) => {
return (
index < songs.length ? songs[index] : undefined;
)
}
- getSongAt 함수는 string | undefined를 반환하는 것으로 유추 된다.
- 두가지 가능한 반환값이 각각 string 과 undefined 이기 때문.
명시적반환타입
//1.
const singSongRecursive = (songs: string[], count = 0): number => {
return (
songs.length ? singSongsRecursive(songs.slice(1), count+1) : count;
)
};
- 함수의 반환문이 함수의 반환 타입으로 할당할 수없는 값을 반환하는 경ㅇ 타입스크립트는 할당 가능성 오류를 표시함.
//2.
const getSongRecordingDate = (song: string): Date | undefined => {
switch (song) {
case "Strange Fruit":
return new Date('April 20, 1939');
case "GreensLeeves";
return "unknown";
// Error: Type 'string' is not assignable to type 'Date'
default:
return undefined;
}
};
- getSongRecordingDate함수는 Date | undefined를 반환하도록 명시적으로 선언했는데,
- 반환문 중 하나가 string을 반환하도록 잘못 제공하고 있다.
함수타입
//1.
const nothingInGivesString: () => string;
- nothingInGivesString변수타입은 매개변수가 없고 string타입을 반환하는 함수이다.
//2.
const inputAndOutput: (songs: string[], count?: number) => number;
- inputAndOutput변수타입은, string[]매개변수와 count선택적매개변수 및 number값을 반환하는 함수.
* 함수타입은 콜백 매개변수(함수로 호출되는 매개변수)를 설명하는데에 자주 사용된다.
//3.
const songs = ['juice', 'shake it off', 'whatup'];
const runOnSongs = (getSongAt: (index: number) => string) => {
for (let i=0; i<songs.length; i+=1) {
console.log(getSongAt(i))
}
}
const getSongAt = (index: number) => {
return (
'${songs[index]}'
);
};
runOnSongs(getSongAt);
const logSong = (song: string) => {
return (
'${song}'
);
};
runOnSongs(logSong);
// 1. Error: Argument of type '(song: string) => string' is not assignable to parameter of type '(index: number) => string'.
// 2. Types of parameters 'song' and 'index' are incompatible.
// 3. Type 'number' is not assignable to type 'string'.
- runOnSongs(logSong)에 대한 오류메시지는 할당 가능성 오류의 예로 몇가지 상세한 단계까지 제공.
- 두 함수를 서로 할당할 수 없다는 오류를 출력할 때 타입스크립트는 일반적으로 3가지 단계제공
1. 두 함수 타입을 출력한다.
2. 일치하지 않는 부분을 지정한다.
3. 일치하지 않는 부분에 대한 정확한 할당가능성오류를 출력
- 오류
1. longSongs: (song: string) => string 은 getSongAt: (index: number) => string 에 할당되도록 제공된 타입이다.
2. longSong의 song 매개변수는, getSongAt의 index 매개변수로 할당된다.
3. song의 string 타입은 index의 number타입에 할당할 수 없다.
- 타입스크립트에서 여러줄로 나타나는 오류가 어려워보일 수 있지만 한줄 한줄씩 읽으며 각 부분이 전달하는 내용을 이해하자.
함수타입 괄호
//타입: string | undefined 유니언을 반환하는 함수
const returnsStringOrUndefined = () => string | undefined;
//타입: undefined 또는 string을 반환하는 함수
const mayneReturnsString: (() => string) | undefined;
매개변수 타입 추론
//1.
const singer: (song: string) => string;
singer = function (song) {
// song: string타입
return 'Singing: ${song.toUpperCase()}!';
};
- singer변수는 string타입의 매개변수를 갖는 함수로 알려져 있으므로
- 나중에 singer가 할당되는 함수 내의 song 매개변수는 string일것이다 는 것을 알 수 있다.
//2.
const songs = ['Call Mee', 'Jolene', 'The Chain'];
songs.forEach((song, index) => {
console.log('${song} is at ${index}')
// song: string, index: number
})
- song과 index매개변수는 타입스크립트에 따라 각각 string과 number로 유추된다.
함수타입별칭
//1.
type StringToNumber = (input: string) => number;
const stringToNumber: StringToNumber;
stringToNumber = (input) => input.length;
stringToNumber = (input) => input.toUpperCase();
// Error: Type 'string' is not assignable to type 'number'.
- StringToNumber타입은 string타입을 받고 number타입을 반환하는 함수의 별칭을 지정한다. 별칭은 이후 변수타입을 설명하는데 사용함.
- 비슷하게 함수매개변수도 함수타입을 참조하는 별칭입력가능.
//2.
type NumberToString = (input: number) => string;
const useNumberToString = (numberToString: NumberToString) => {
console.log('The string id: ${numberToString(1234)});
};
usesNumberToString((input) => '${}! Hooray!');
usesNumberToString((input) => input+2);
//Error: Type 'number' is not assignable to type 'string';
- useNumberToString함수는 함수타입 별칭인 NumberToString의 단일 매개변수를 가진다.
- 타입별칭은 특히 함수타입에 유용함.
- 타입별칭을 이용하면 반복적으로 작성하는 매개변수와 반환타입을 갖는 코드공간을 많이 절약할 수 있다.
void 타입
//1.
const lonSong = (song: string | undefined): void => {
if (!song) {
return;
}
console.log('${song}');
return true;
// Error: Type 'boolean' is not assignable to type 'void';
};
- 반환타입이 void 인 함수는 값을 반환하지 않을 수 있다.
- logSong 함수는 void를 반환하도록 선언되었으므로 값 반환을 허용하지 않음.
- 함수타입 선언시 void반환타입은 매우 유용하다.
//2.
const songLogger:(song:string) => void;
songLogger = (song) => {
console.log('${songs}');
};
songLogger('Heart of Glass');
- 함수타입 선언할 때 void를 사용하면 함수에서 반환되는 모든 값은 무시된다.
- songLogger 변수는 song: string을 받고, 값을 반환하지 않는 함수이다.
//3.
const returnsVoid = () => {
return;
};
const lazyValue: string | undefined;
lazyValue = returnsVoid();
//Error: Type 'void' is not assingnable to type 'string|undefined'
- 자바스크립트함수는 실제값이 반환되지 않으면 기본으로 모두 undefined 를 반환하지만, void는 undefined와 다르다.
- void는 함수의 반환 타입이 무시된다는 것을 의미하고, undefined 는 반환되는 리터럴값 이다.
- undefined 를 포함하는 대신 void타입의 값을 할당하려고 하면 타입오류 나타남.
//4.
const records: string[] = [];
const saveRecords = (newRecords: string[]) => {
newRecords.forEach(record => records.push(record));
}
saveRecords(['21', 'Come On Over', 'The Bodyguard'])
- undefined 와 void 를 구분해서 사용하면 매우 유용하다.
- 특히, void를 반환하도록 선언 된 타입 위치에 전달된 함수가 반환 된 모든 값을 무시하도록 설정할 떄 유용하다.
- 예를들어, 배열의 내장 forEach 메서드는 void를 반환하는 콜백을 받는다.
- forEach에 제공되는 함수는 원하는 모든 값을 반환할 수 있다.
- saveRecords 함수의 records.push(record) 는 number(배열의 .push()에서 반환된 값)를 반환하지만, 여전히 newRecords.forEach 에 전달 된 화살표함수에 대한 반환값이 허용된다.
- void 타입은 자바스크립트가 아닌 함수의 반환 타입을 선언하는데 사용하는 타입스크립트 키워드.
- void 타입은 함수의 반환값이 자체적으로 반환 될 수 있는 값도 아니고, 사용하기 위한 것도 아님.
never반환타입
const fail = (message: string): never => {
throw new Error('Invariant failure: ${message}.');
};
const workWithUnsafeParam = (param: unknown) => {
if (typeof param !== 'string') {
fail('param should be a string, not ${typeof param}')
}
param.toUpperCase();
};
- 함수가 절대 반환하지 않도록 의도하려면 명시적 : never 타입 애너테이션을 추가해 해당 함수를 호출한 후 모든 코드가 실행 되지 않음을 나타낸다.
- fail함수는 오류만 발생시키므로 param의 타입을 string으로 좁혀서 타입스크립트의 제어흐름분석을 도와준다.
- never는 void와는 다름.
- void는 아무것도 반환하지 않는 함수를 위한 것이고,
- never는 절대 반환하지 않는 함수를 위한 것.
함수오버로드
오버로드 시그니처 overload signature
라고 불리는 타입스크립트 구문으로 설명할 수 있다.//1.
function createDate(timestamp: number): Date;
function createDate(month: number, day: number, year: number): Date;
const createDate = (monthOrTimestamp: number, day?: number, year?: number) => {
return (
day === undefined || year === undefined
? new Date(monthOrTimestamp)
: new Date(year, monthOrTimestamp, day)
);
};
createDate(554356800);
createDate(7, 27, 1987);
createDate(4, 1);
// Error: No overload expects 2 arguments, but overloads do exist that expect either 1 or 3 arguments
- createDate 함수는 1개의 timestamp 매개변수 또는 3개의 매개변수(month, day, year)를 사용해 호출.
- 허용된 수의 인수를 사용해 호출할 수 있지만 2개의 인수를 사용해 호출하면 2개의 인수를 허용하는 오버로드 시그니처가 없기 때문에 타입오류 발생한다.
- 함수오버로드는 복잡하고 설명하기 어려운 함수타입에 사용하는 최후의 수단. 함수를 단순하게 유지하고 가능하면 함수 오버로드를 사용하지 않는 것이 좋음.
유연한 배열과 고정된 튜플
//1.
const elements = [true, null, undefined, 42];
elements.push('even', ['more']);
//elements배열의 값: [true, null, undefined, 42, 'even', ['more']]
- 자바스크립트 배열은 매우 유연하고 내부에 모든 타입의 값을 혼합해서 저장할 수 있다.
- 대부분의 개별 자바스크립트 배열은 하나의 특정 타입의 값만 가진다.
- 다른 타입의 값을 추가하게 되면 배열을 읽을 때 혼란을 줄 수 있다.
- 타입스크립트는 초기배열에 어떤 데이터 타입이 있는지 기억하고, 배열이 해당 데이터타입에서만 작동하도록 제한한다.
//2.
const warriors = ['Artemisia', 'Boudica'];
warriors.push('Zenobia');
warriors.push(true);
//Error: Argument of type 'boolean' is not assignable to parameter of type 'string'.
- warriors배열이 초기에 string타입의 값을 포함한다는 것을 알고 있으므로 이후 string 타입의 값 추가는 허용하지만 다른 데이터타입 추가는 허용하지 않는다.
- 타입스크립트가 초기배열에 담긴 요소를 통해 배열의 타입을 유추하는 방법은 변수의 초기값에서 변수타입을 유추하는 방법과 유사함.
- 타입스크립트는 값이 할당되는 방식에서 코드의 의도 된 타입을 이해ㅏㅎ려고 시도하며 배열도 그렇다.
배열타입
//1.
const arrayOfNumbers: number[];
arrayOfNumbers = [4.8,45,46,23,12];
- 배열 타입은 Array<number> 같은 구문으로도 작성할 수 있다. 하지만 대부분은 더 간단한 number[]를 선호.
배열과 함수타입
const createStrings: () => string[];
//타입은 string배열을 반환하는 함수
const stringCreators: (() => string)[];
//타입은 각각의 string을 반환하는 함수배열
- 함수타입인 createStrings, 배열타입인 stringCreator 와 동일하지 않다.
유니언타입배열
//1.
* 두 타입은 동일하지 않다.
const stringOrArrayOfNumbers: string | number[];
//타입은 string 또는 number의 배열
const arrayOfStringOrNumbers: (stirng | number)[];
//타입은 각각 number 또는 string인 요소의 배열
- 타입스크립트는 배열의 선언에서 두가지 이상의 요소타입이 포함 되는 경우, 유니언타입 배열임을 알게 된다.
- 즉, 배열의 요소타입은 배열에 담긴 요소에 대한 모든 가능한 타입의 집합.
//2.
//타입: (stirng | undefined)[]
const namesMaybe = [
'Aqualtune',
'Blenda',
undefined
];
- namesMayne는 string값과 undefined 값을 모두 가지므로 (string | undefined)[] 타입이다.
any배열의 진화
any[]
로 취급하고 모든 콘텐츠를 받을 수 있다.any[]
배열이 변경되는 것도 좋아하지 않음.//1.
//타입: any[]
const values = [];
//타입: string[]
values.push('');
//타입: (number | string)[]
values[0] = 0;
- values배열은 any요소를 갖고 시작해 string요소를 포함하도록 바뀐 다음, 다시 number|string 요소로 바뀐다.
- 변수와 마찬가지로 배열이 any타입이 되도록 허용하거나 일반적으로 any타입을 사용하도록 허용하면 타입스크립트의 타입검사목적을 부분적으로 무효화함. 타입스크립트는 값의 타입을 알 떄 가장 잘 작동한다.
다차원배열
[]대괄호
를 가진다.//1.
const arrayOfArrayOfNumbers: number[][];
arrayOfArrayOfNumbers = [
[1,2,3],
[2,4,6],
[3,5,7]
];
- 3차원배열 또는 배열의 배열의 배열에는 세개의 []가 있고
- 4차원배열에는 네개의 [] 5차원에는 ...
- 다차원배열타입은 새로운개념이 아님
- 2차원 배열은 원래의 타입을 가지며 끝에 []가 있고, 그 뒤에 []을 추가하는 것.
//2.
const arrayOfArrayOfNumbers: (number[])[];
- arrayOfArraysOfNumbers배열은 number[][]타입이고 (number[])[]으로 나타낼 수 있다.
배열멤버
//1.
const defenders = ['Clarenza', 'Dina'];
//타입: string
const defender = defenders[0];
- defenders배열은 string[]타입이므로 defender는 string타입이다.
- 유니언타입으로 된 배열의 멤버는 그 자체로 동일한 유니언타입이다.
//2.
const solidersOrDates = ['Deborah Sampson', new Date(1782, 6, 3)];
//타입: string | Date
const solidersOrDate = solidersOrDates[0];
- solidersOrDates는 (string | Date)[]타입이므로 solidersOrDate 변수는 string | Date 타입이다.
주의사항: 불안정한 멤버
//1.
const withElements = (elements: string[]) => {
console.log(elements[9001].length);
//타입오류없음
};
withElements(["It's", "over"]);
- 런타입 시 Cannot read property 'length' of undefined 가 발생하며 충돌할거라고 유추할 수 있지만, 타입스크립트는 검색된 배열의 멤버가 존재하는지 의도적으로 확인하지 않는다.
- elements[9001]은 undefined 가 아니라 string 타입으로 간주된다.
- 타입스크립트에는 배열조회를 더 제한하고 타입을 안전하게 만드는 noUncheckedIndexedAccess 플래그가 있지만, 이 플래그는 매우 엄격해서 사용 잘 하지않음.
스프레드
//1.
//타입: string[]
const soldiers = ['harriet', 'joan', 'khutulun'];
//타입: number[]
const soldierAges = [90, 19, 45];
//타입: (string | number)[]
const conjoined = [...soldiers, ...soldierAges];
- conjoined 배열은 string타입과 number타입 값을 모두 포함하므로
나머지 매개변수 스프레드
const logWarriors = (greeting: string, ...names: string[]) => {
for (const name of names) {
console.log('${greeting}, ${name}!')
}
}
const warriors = ['Cathay Williams', 'Lozen', 'Nzinga']
logWorriors('Hello', ...worriors);
const birthYears = [1844, 1840, 1583];
logWarriors('Born in', ...birthYears);
//Error: Argument of type 'number' is not assignable to parameter of type 'string'.
- logWarriors함수는 ...names 나머지 매개변수로 string 값만 받는다.
- string[]타입배열을 스프레드하는 것은 허용되지만 number[]는 허용되지 않음.
튜플
튜플tuple
을 사용하는 것이 유용하다.//1.
const yearAndWarrior: [number, string];
yearAndWarrior = [530, 'Tomyris'];
yearAndWarrior = [false, 'Tomyris'];
//Error: Type 'boolean' is not assignable to type 'number'.
yearAndWarrior = [530];
//Error: Type '[number]' is not assignable to type '[number, string]'.
// Source has 1 element(s) but target requires 2.
- yearAndWarrior배열은 인덱스 0에 number타입 값을 갖고, 인덱스 1에 string값을 갖는 튜플타입으로 선언됨.
- 자바스크립트에서는 단일 조건을 기반으로 두개의 변수에 초기값을 설정하는 것처럼 한번에 여러 값을 할당하기 위해 튜플과 배열구조분해할당array destructuring을 함께 자주 사용한다.
//2.
// year 타입 : number
// warrior 타입 : string
const [year, warrior] = Math.random() > 0.5 ? [340, 'Archidamia'] : [1828, 'Rani or Jhansi']
- 타입스크립트는 위 코드에서 year은 항상 number이고, warrior는 항상 string임을 인식한다.
튜플할당가능성
//1.
// 타입 : (boolwan | number)[]
const pairLoose = [false, 123];
const pairTupleLoose: [boolean, number] = pairLoose;
// Error: Type '(number | boolean)[]' is not assignable to type '[boolean, number]'
// Target requires 2 element(s) but source may have fewer.
- pairLoose 내부에 [boolean, number]가 있는 것을 볼 수 있지만, 타입스크립트는 더 일반적인 (boolean | number)[] 타입으로 유추한다.
- pairLoose가 [boolean, number] 자체로 선언 된 경우 pairTupleLoose에 대한 값 할당이 허용되었을 것.
- 하지만 타입스크립트는 튜플타입의 튜플에 얼마나 많은 멤버가 있는지 알고 있기 떄문에 길이가 다른 튜플은 서로 할당할 수 없다.
//2.
const tupleThree: [boolean, number, string] = [false, 1583, 'Nzinga'];
const tupleTwoExact: [boolean, number] = [tupleThree[0], tupleThree[1]];
const tupleTwoExtra: [boolean, number] = tupleThree;
//Error: Type '[boolean, number, string]' is not assignable to typt '[boolean, number]'.
// Source has 3 element(s) but target allows only 2.
나머지 매개변수로서의 튜플
//1.
const logPair = (name: string, value: number) => {
console.log('${name} has ${value}')
}
const pairArray = ['Amage', 1]
logPair(...pairArray);
const pairTupleCorrect: [string, number] = []
.
.
.
.
..
.. 미완성.
..
..
.
..
..
.
명시적 튜플 타입
//1.
//반환타입: [string, number]
const firstCharAndSizeExplicit = (input: string): [string, number] => {
return (
[input[0], input.length]
);
}
//firstChar타입: string
//size타입: number
const [firstChar, size] = firstCharAndSizeExplicit('Cathay Williams');
const 어서션
//1.
//타입: (string | number)[]
const unionArray = [1157, 'Tomoe'];
//타입: readonly [1157, 'Tomoe']
const readonlyTuple = [1157, 'Tomoe'] as const;
- 배열리터럴 뒤에 as const 가 배치되면, 배열이 튜플로 처리되어야함을 나타냄.
- const 어서션은 유연한 크기의 배열을 고정된 크기의 튜플로 전환하는 것을 넘어서, 해당 튜플이 읽기 전용이고 값 수정이 예상되는 곳에서 사용할 수 없음을 나타냄
//2.
const pairMutable: [number, string] = [1157, 'Tomoe'];
pairMutable[0] = 1247;
const pairAlsoMutable: [number, string] = [1157, 'Tomoe'] as const
//Error: The type 'readonly [1157, 'Tomoe']' is 'readonly'
// and cannot be assigned to the mutable type '[number, string]'.
const pairConst = [1157, 'Tomoe'] as const;
pairConst[0] = 1247;
//Error: Cannot assign to '0' because it is a read-only property.
- pairMutable은 전형적인 명서적 튜플 타입이므로 수정될 수 있다.
- 그러나 as const 는 값이 변경될 수 있는 pairAlsoMutable에 할당할 수 없도록하고, 상수 pairConst의 멤버는 수정을 허용하지 않는다.
- 실제로 읽기전용 튜플은 함수반환에 편리하다.
- 튜플을 반환하는 함수로부터 반환된 값은 보통 즉시 구조화되지 않으므로 읽기전용인 튜플은 함수를 사용하는데에 방해가 되지않음.
//3.
//반환타입: readonly[string, number]
const forstCharAndSizeAsConst = (input: string) => {
return (
[input[0], input.length] as const;
)
}
//firstChar타입: string
//size타입: number
const [firstChar, size] = firstCharAndSizeAsConst('Ching Shih');
- firstCharAndSizeAsConst는 읽기전용 [string, number]를 반환하지만, 이를 사용하는 코드는 해당 튜플에서 값을 찾는 것에만 관심을 둔다.