any는 프로젝트에 존재하지 않아야 하고 무조건적으로 배척해야 한다고 생각했지만, 챕터에 any다루기가 있는 것으로 보아 피할 수 없는 경우가 반드시 존재하거나,
옳은 방향으로 사용한다면 많은 이점을 가져다 준다거나 등의 이유가 있을 것으로 보임.
어느 방향인지 알아보는 것을 목표로 스터디.
아래 코드처럼 Foo, Bar 둘 다 할당 가능하다면 오류를 제거하는 방법은 두 가지.
interface Foo { foo: string; }
interface Bar { bar: string; }
declare function expressionReturningFoo(): Foo;
function processBar(b: Bar) { /* ... */ }
function f() {
const x = expressionReturningFoo();
processBar(x);
// ~ Argument of type 'Foo' is not assignable to
// parameter of type 'Bar'
}
변수에 any타입을 선언하거나, 매개변수로 전달할 때 타입 단언을 사용.
interface Foo { foo: string; }
interface Bar { bar: string; }
declare function expressionReturningFoo(): Foo;
function processBar(b: Bar) { /* ... */ }
function f1() {
const x: any = expressionReturningFoo(); // Don't do this
processBar(x);
}
function f2() {
const x = expressionReturningFoo();
processBar(x as any); // Prefer this
}
any는 javascript의 모든 값을 표현하는 넓은 범위의 타입.
이는 일반적인 상황에서는 any보다는 구체적인 값으로 표현할 수 있는 타입이 존재하기도 하다는 뜻.
function getLengthBad(array: any) {
return array.length;
}
// better than above.
function getLength(array: any[]) {
return array.length;
}
위 코드에서 getLength가 getLengthBad보다 나은 이유는 세 가지 이다.
배열이 아닌 값을 넣어서 호출하면 에러를 잡아내지 못하고, 잡아내는 부분에서 차이가 있다.
함수의 매개변수가 객체인 것은 알고 있지만, 값을 알 수 없다면 다음과 같이 선언하면 된다.
function paramTest({[key: string]: any}) {
...
}
위의 방식 대신 모든 비기본형인 object를 사용할 수 있지만, 차이점이 존재한다.
key를 열거할 수 있지만, 속성에 접근할 수는 없다는 차이점이 있다.
결론: any를 사용하는 경우에도 최소한의 타입을 추론 가능하도록 좁힐 수 있다.
책에서 나온 것처럼 거의 배열 형태일 경우에만 활용이 가능할 것으로 보인다.
서론: 함수를 작성하다 보면, 외부로 드러난 타입 정의는 간단하지만 내부 로직이 복잡해서 안전한 타입으로 구현하기 힘든 경우가 많음.
함수의 모든 부분을 안전한 타입으로 구현하는 것이 이상적 -> But, 불필요한 예외 사항까지 고려하여 타입 정보를 힘들게 구현할 필요는 없음.
함수 내부에서는 타입 단언을 사용하고 외부로 드러나는 부분만 타입 정의를 명확히 명시하는 정도로 끝내는 것이 나음.
=> 프로젝트 전반에 타입 단언이 들어있는 것보단, 제대로 타입이 정의된 함수 안으로 감추는 것이 더 좋은 설계임.
결론: 결국 예제에서도 불가피한 경우라고 얘기했고, 현실적으로 리소스 낭비일 경우에 더 나은 방법을 제시해주는 것으로 보임.
any의 역사를 얘기하는 것이 아님.
noImplictAny가 설정된 상태에서 변수의 타입이 암시적 any인 경우에만 일어남.
any를 암시적으로 선언해서 any가 진화되는 것보다 명시적으로 선언해서 타입을 유지시키는 것이 안전한 방법임.
결론: 타입이 변할 수 있는 것을 인지하고 이해할 수 있어야 하고, 사용하지 않는 것이 좋을 것 같음.
any가 강력하면서도 위험한 이유는 두 가지로부터 비롯됨.
한 집합은 다른모든 집합의 부분 집합이면서 동시에 상위 집합이 될 수 없기 때문에, any는 타입 시스템과 상충되는 면이 있음.
unknown은 any의 첫 번째 속성을 만족하지만 두 번째 속성은 만족하지 않음.
함수의 반환 타입을 unknown으로 정하고, 의도한 값을 반환할 것을 알기 때문에 호출부에서 타입 단언을 사용해야 함.
결론: 어떠한 값이 있지만 그 타입을 알지 못하는 경우에 unknown을 사용하면 됨.
근데 책에서 설명한 예제에서 반환 타입을 의도한 것으로 반환하도록 아는데 왜 unkown을 사용하는지??
자바스크립트의 특징 중 하나는. 객체와 클래스에 임의의 속성을 추가하는 것.
window.monkey = 'hi';
document.monkey = 'hello';
하지만, 타입시스템으로 넘어오면 임의로 추가한 속성들은 찾을 수 없음.
가장 간단한 방법이 다음과 같은 방법.
(document as any).monkey = 'hello~~';
하지만, 타입 안전성을 상실하고 언어 서비스를 사용할 수 없게됨.
=> 보강? argumentation 조사
npx type-coverage
npx type-coverage --detail
각각, any가 아니거나 any의 별치이 아닌 타입을 갖음을 알려주고 / any 타입이 존재하는 곳을 알려줌.
Java + Spring 쓸 때, Eclipse 혹은 InteliJ에서 제공하는 기능과 동일.