December 16, 2020
: types
와 같은 형태로 타입을 지정해줄 수 있다.// 코틀린때처럼, 리턴값의 타입도 정해줄 수 있는듯 하다.
// 별도로 정해주지 않는다면, 알아서 설정하는 듯 함.
function func(a : string, b : string) : string {
return a+b;
}
const string : string = func('타입', '스크립트');
function func(a, b){
return a+b;
}
const string = func('타입', '스크립트');
function add(a : number, b : number) : number {
return a+b;
}
const result : string = add(1,2);
// 'number' 형식은 'string' 형식에 할당할 수 없습니다.ts(2322)
let bool : boolean;
let bool2 : boolean = false;
let num : number;
let six : number = 6;
let pie : number = 3.14;
let hex: number = 0xf00d; // 61453
let binary: number = 0b1010; // 10
let octal: number = 0o744; // 484
let infinity: number = Infinity;
let nan : number = NaN;
let str : string;
let myName : string = '상민';
let myAge : number = 26;
let introduce : string = `내 이름은 ${myName} 입니다. 나이는 ${myAge} 입니다.`;
// 1. 타입[]
let number : number[] = [1,2,3,4,5,6];
// 2. Array<타입> - 코틀린을 할 때에는 이 방법을 썼다.
let classes : Array<string> = ['바드', '워로드', '블래스터', '디스트로이어', '서머너', '아르카나'];
// 1. (타입1 | 타입2 ...)[]
let array1 : (string | number | object)[] = [1, '타입', {type : '객체'}];
// 2. Array<타입1 | 타입2 ...>
let array2 : Array<string | number | Array<number>> = [2, '스크립트', [1,2,3]];
let array3 : Array<any> = [0,2,{},[],'타입',true];
let array4 : any[] = [1,2,{},[],'스크립트',false];
interface Classes {
name : string,
class : string,
level : number
}
let classesArr : Array<Classes> = [
{
name : '모여요꿈동산',
class : '바드',
level : 1369
},
{
name : '워로드는뒤로점프',
class : '워로드',
level : 1031
}
]
코틀린에서 내가 만든 클래스들을 타입으로 사용했었다.
let array5 : readonly number[] = [1,2,3,4];
let array6 : ReadonlyArray<number> = [1,2,3,4];
let turple : [string, number];
turple = ['타입스트립트', 1];
turple = [1, '타입스크립트']; // 타입 에러
turple = ['타입스트립트', 1, 5]; // 타입 에러 + 갯수 에러
let turple2 : [number, string, boolean][];
turple2 = [[1, '타입', true], [2, '스크립트', false]]
let turple3 : [string, number]
turple3 = ['a', 1];
turple3 = ['b', 2];
turple3.push(3); // 가능
turple3.push(true); // 첫 Turple 지정에 문자열과 숫자만 가능하도록 설정되어있기 때문에, 타입 에러가 발생함
enum Week {
Sun, // (enum member) Week.Sun = 0
Mon, // (enum member) Week.Sun = 1
Tue, // (enum member) Week.Sun = 2
Wed, // (enum member) Week.Sun = 3
Thu, // (enum member) Week.Sun = 4
Fri, // (enum member) Week.Sun = 5
Sat // (enum member) Week.Sun = 6
}
암만해봐도 숫자는 안되는것 같다.
순차적으로 증가할 경우 사용할 수 있을것같긴한데.. 솔직히 아직은 왜있는지 모르겠다.
enum Week2 {
Sun, // (enum member) Week.Sun = 0
Mon, // (enum member) Week.Sun = 1
Tue = 30, // (enum member) Week.Sun = 30
Wed, // (enum member) Week.Sun = 31
Thu, // (enum member) Week.Sun = 32
Fri, // (enum member) Week.Sun = 33
Sat // (enum member) Week.Sun = 34
}
Week.Sun // 0
Week[0] // Sun
let any : any = 123
any = '타입스크립트'
any = {};
any = null;
const arr : Array<any> = [1, '타입스크립트', {}, [], true];
const arr2 : any[] = [1, '타입스크립트', {}, [], true];
"noImplicitAny": true
를 통해 Any 사용시 에러를 발생시킬 수 있다.그치만.. 난 any가 좋은걸..
let a : any = 123;
let u : unknown = 123;
let v1 : boolean = a; // Any는 어디든 가능
let v2 : number = u; // unknown 형식은 any를 제외한 다른 타입에는 할당이 불가능함
let v3 : any = u; // Any는 unknown을 할당할 받을 수 있음
let v4 : number = u as number; // unknown중에서 특정 타입을 단언하면 할당할 수 있다.
Unknown타입은 타입단언이나 타입가드를 필요로 한다고 함. 이후 포스트에서 다룰예정
interface User {
id : string,
password : string
}
interface Result {
success : boolean,
value : unknown
};
function Login(user : User) : Result {
if(user.id) return {
success : true,
value : {
id : 'sangmin802',
name : '상민이'
}
}
return {
success : false,
value : new Error('없는 아이디입니다.')
}
}
let obj : object = {};
let arr : object = [];
let func : object = function(){};
let nullValue : object = null;
let date : object = new Date();
object
로 지정하기보단, 객체 속성들의 타입을 개별적으로 지정해준다. let user : {name : string, age : number} = {
name : 'sangmin',
age : 26
}
interface
나 type
을 사용한다. interface User {
name : string,
age : number
}
let user : User = {
name : 'sangmin',
age : 26
}
Null
과 Undefined
는 모든 타입의 하위 타입으로, 대부분의 타입에 할당될 수 있으며 서로에게도 할당이 가능하다.let num : number = undefined;
let str : string = null;
let obj : {id : string, age : number} = undefined;
let arr : any[]= null;
let und : undefined = null;
let nul : null = undefined;
let voi : void = null; // void는 undefined가 불가능
return
값이 없는 함수)에서 사용된다. function consoleHello(msg : string = '안녕하세요') : void {
console.log(msg);
}
const hi : void = consoleHello();
console.log(hi) // 억지로 반환시키면 undefined를 반환시킴
Never
는 절대 발생하지 않을 값을 뜻하며, 어떠한 타입도 적용할 수 없다. function error(message: string): never {
throw new Error(message);
}
void
랑 용도가 비슷해보이는데..?
Union
이라고 한다. |
를 통해 타입을 구분하며, ()
는 선택사항이다.let value : (string | number); // string | number
value = '안녕하세요';
value = 3;
Union
이라는 타입명이 있는건 아니고, 위와같은 상황?을 이야기하는듯 하다.
&
를 사용해 2개이상의 타입을 조합하는 경우이다. interface User {
name : string,
age : number
}
interface Authorized {
authorized : boolean
}
const user : User & Authorized = {
name : 'sangmin',
age : 26,
authorized : true
}
const func = (x : number = 1, y : number = 3) : number => {
return x + y;
}
console.log(func()) // 4
let func2 : (arg1 : number, arg2 : number) => number;
func2 = function(x = 1, y = 3){
return x+y;
}
let func3 : () => void;
func3 = function(){
console.log('반환하는거 없습니다.')
}
const a = "문자열" // a : "문자열
const
도 별도로 타입을 입력해주면, 해당 타입이 뜨긴 함
let a = "문자열" // a : string
let
과 const
는 타입을 추론하는 규칙이 다르다. 이는 합리적인것이, let
의 경우 타입만 동일하다면 값이 바꿀수 있지만, const
는 다른 값이 대입될 수 없기 때문에 그냥 타입처럼 박히는? 것이다.let num = 12;
num = '타입스크립트'; // 'string' 형식은 'number' 형식에 할당할 수 없습니다.ts(2322)
// 상황 설명
// val : 문자열과 숫자열을 받을 수 있다.
// isNumber : 숫자인지 아닌지 boolean으로 받는다.
// 개발자는 isNumber가 true라면 val이 number타입이라는것을 알고있지만, 타입스크립트는 알지 못한다.
// 따라서, func1 같은 경우 toFixed메소드는 string타입에서 사용할 수 없다는 에러를 출력하게된다.
function func1(val : string | number, isNumber : boolean) : void{
if(isNumber) val.toFixed(2);
}
// number타입인 val만 toFixed 메소드가 실행되도록 한다.
function func2(val : string | number, isNumber : boolean) : void{
if(isNumber) (val as number).toFixed(2);
}
!
를 통해, Null
이나 undefined
값이 아님을 단언할 수 있다. function func(x : number | null | undefined) : string {
// 조건문을 활용할 경우
if(x) return x.toFixed(2);
// 위의 타입 단언을 사용할 경우
return (x as number).toFixed(2);
// Non-null(null이나 undefined가 아닌)연산자 !를 사용할 경우
return x!.toFixed(2);
}
val is Type
의 형태로, 변수의 상태를 반환 타입으로 명시한 함수이다 // 변수의 타입을 매번 보장하기 위해 타입단언을 여러번 사용하게되는 경우가 있다.
function someFunc(val: string | number, isNumber: boolean) {
if (isNumber) {
(val as number).toFixed(2);
isNaN(val as number);
} else {
(val as string).split('');
(val as string).toUpperCase();
(val as string).length;
}
}
// 타입가드 val is Type
// 솔직히 잘 모르겠음.. 그냥 number인지 확인하는 함수를 별도로 밖으로 뺀 느낌이다.
// val is number를 그냥 boolean으로 바꿔서 하는거랑 다른게 뭐가 있나..?
function isNumber(val : string | number) : val is number {
return typeof val === 'number';
}
function someFunc(val: string | number) {
if (isNumber(val)) {
val.toFixed(2);
isNaN(val);
} else {
val.split('');
val.toUpperCase();
val.length;
}
}
typeof
, in
그리고 instanceof
연산자를 직접 사용하는 타입 가드. // typeof 연산자
// 당연히 object는 사용하는것을 비추천
function funcTypeof(val : string | number){
if(typeof val === 'number'){
val.toFixed(2);
isNaN(val);
}else{
val.split('');
val.toUpperCase();
val.length;
}
}
// in 연산자
// 속성 in 객체명
// 명시된 속성이 객체에 존재하는지 여부 파악
// in을 사용하려면, any타입의 변수여야한다.
// 근데 작동은 안되는데..?
function funcIn(val : any){
if('toFixed' in val){
val.toFixed(2);
isNaN(val);
}else if('split' in val){
val.split('');
val.toUpperCase();
val.length;
}
}
// instance 연산자
// 개인적으로 프로토타입을 만드는것을 선호하지 않기 때문에 패스