circumspect
는 TypeScript/JavaScript 코드를 더 안전하게 만드는 함수 세트입니다. 이러한 함수에는 invariant
, warning
, assertNever
등이 포함됩니다.
invariant
및 assertNever
와 같이 코드를 더 안전하게 만들 수 있는 유용한 함수가 많이 있습니다. 이러한 함수 중 다수는 별도의 npm 패키지(예: invariant
)로 제공됩니다. 그러나 각 기능에 대해 새 패키지(그리고 대부분의 경우 @types
대응 패키지도 포함)를 설치하는 것은 그리 편리하지 않습니다. 또한 해당 패키지는 일반적으로 해당 기능을 기본 내보내기로 내보내므로 VSCode 자동 가져오기가 제대로 작동하지 않습니다.
이 라이브러리는 코드를 더욱 안전하게 만드는 기능을 한 곳에 통합합니다. circumspect
은 모든 것을 포함하는 단일 종속성입니다. 그리고 circumspect
에서 제공하는 모든 기능에 내보내기라는 이름이 지정되므로 VSCode 자동 가져오기가 예상대로 작동합니다.
게다가, circumspect
는 100% TypeScript로 작성되었기 때문에 기본적으로 모든 함수가 올바르게 입력됩니다. 따라서 별도의 @types
패키지를 설치할 필요가 없습니다.
원사 사용:
yarn add circumspect
npm 사용:
npm install circumspect
invariant
warning
assertNever
nonNull
invariant
invariant ( value : unknown , message ?: string ) : asserts value
value: unknown
은 진실성을 보장하려는 값입니다.
message?: string
전달된 value
이 거짓일 때 발생하는 오류에 포함될 선택적 오류 메시지입니다. 이 사용자 정의 오류 메시지는 개발 중에만 표시됩니다. 프로덕션에서는 일반 오류( 'Invariant violation'
)가 대신 표시되고 message
매개변수는 무시됩니다.
asserts value
, 함수는 단순히 value
의 유형을 진실로 좁히고 아무것도 반환하지 않음을 의미합니다. invariant
지정된 value
이 진실임을 보장합니다. 그렇지 않은 경우 지정된 message
포함된 오류가 발생합니다(개발에만 해당). 이 함수는 모든 잘못된 값(예: null
및 undefined
)을 제외하여 value
유형을 적절하게 좁힙니다.
invariant
잠재적으로 거짓일 수 있는 값이 있을 때마다 사용해야 하지만 특정 상황에서는 그 값이 참이어야 한다고 확신할 수 있습니다. 즉, 값이 참이라는 사실은 불변이며, 값이 거짓인 경우 불변이 위반되었으므로 오류가 발생해야 합니다.
message
인수는 프로덕션에서 완전히 무시되므로 프로덕션 빌드에서는 코드에서 완전히 제거할 수 있습니다. 이를 수행하는 방법을 보려면 최적화 섹션을 참조하세요.
declare const user : User | null | undefined ;
invariant ( user , 'The user is missing!' ) ;
user ; // If we get here, the type is narrowed to `User`
이 예에서 user
개체는 잠재적으로 null
이거나 정의되지 undefined
수 있습니다(즉, 거짓). 그렇다면 불변 위반이 발생하고 invariant
함수가 발생합니다. 그렇지 않으면 단순히 반환되며 user
실제로 사용자 개체를 가리킨다는 것을 알 수 있습니다.
warning
warning ( value : unknown , message : string ) : void
value: unknown
은 확인하려는 값입니다. 거짓이면 콘솔에 경고가 표시됩니다.
message: string
콘솔에 기록될 경고 메시지입니다.
void
함수는 아무것도 반환하지 않습니다. warning
지정된 value
이 거짓인 경우 지정된 message
와 함께 콘솔에 경고를 발행합니다. 경고는 개발 중에만 발행됩니다. 프로덕션에서는 이 함수가 아무 작업도 수행하지 않습니다.
일부 값이 거짓인 경우 개발 전용 경고를 발행할 때마다 사용해야 하며, 이는 개발자가 경고 메시지에 보고되는 중요하지 않은 문제를 수정하도록 안내하는 데 도움이 됩니다.
warning
프로덕션에서 아무 작업도 수행하지 않으므로 프로덕션 빌드의 코드에서 이 함수에 대한 호출을 완전히 제거할 수 있습니다. 이를 수행하는 방법을 보려면 최적화 섹션을 참조하십시오.
declare const mode : 'auto' | 'default' | 'slow' | 'fast' ;
warning (
mode !== 'auto' ,
'Mode "auto" has been deprecated. Please use "default" instead.' ,
) ;
이 예에서는 mode
'auto'
인 경우 지원 중단 경고를 발행하려고 합니다. 그렇게 하려면 거짓 값을 전달해야 합니다. 이것이 바로 mode !== 'auto'
전달하는 이유입니다. 이는 mode
'auto'
인 경우에만 거짓입니다.
어떤 경우에는 false
직접 전달하는 것이 합리적입니다. 예를 들어:
declare const languages : Language [ ] ;
declare const defaultLanguage : Language ;
declare const langName : string ;
let lang = languages . find ( ( { name } ) => name === langName ) ;
if ( ! lang ) {
warning (
false ,
`Language with name " ${ langName } " not found. Falling back to the default language.` ,
) ;
lang = defaultLanguage ;
}
assertNever
assertNever ( value : never ) : never
value: never
. never
는 함수가 절대 반환되지 않음을 의미합니다. 실제로 호출되면 오류가 발생합니다. assertNever
공용체 유형의 모든 변형이 소진되었는지 확인하는 데 사용해야 합니다.
value
의 모든 공용체 변형이 소진된 경우 value
를 사용하여 assertNever
호출할 때 컴파일러 오류가 발생하지 않습니다. 왜냐하면 value
해당 시점에서 never
유형으로 간주되고 런타임 시 assertNever
호출하는 지점에 도달하지 않기 때문입니다. 오류가 발생하지 않습니다.
그러나 모든 공용체 변형이 소진되지 않은 경우 never
아닌 다른 값으로 assertNever
호출하므로 다음과 같은 컴파일러 오류가 발생합니다.
Argument of type 'x' is not assignable to parameter of type 'never'.
누락된 변형을 처리하여 수정할 수 있습니다. TypeScript 문서에서 Union Exhaustiveness Checking 및 assertNever
에 대해 자세히 알아볼 수 있습니다.
declare const state : 'loading' | 'done' | 'error' ;
switch ( state ) {
case 'loading' :
return < Loading / > ;
case 'done' :
return < Done / > ;
case 'error' :
return < Error / > ;
}
이 예에서는 switch
문 내에서 'loading'
, 'done'
및 'error'
가능한 모든 상태를 처리합니다.
하지만 나중에 'pending'
과 같은 다른 상태를 추가하면 어떻게 될까요?
switch
문이 'pending'
처리하지 않는다는 사실은 감지되지 않습니다.
해결책은 가능한 모든 상태가 처리되었다고 주장하는 default
사례를 갖는 것입니다.
switch ( state ) {
...
default :
return assertNever ( state ) ;
}
따라서 모든 상태 변형이 처리되면 컴파일 시간 오류가 발생하지 않습니다. 그러나 새로운 'pending'
상태를 추가하면 다음과 같은 컴파일러 오류가 발생합니다.
Argument of type 'string' is not assignable to parameter of type 'never'.
switch
내부의 'pending'
상태를 처리하여 이 오류를 해결할 수 있습니다.
이 예제에서 볼 수 있듯이, assertNever
가능한 모든 사례를 항상 처리했는지 확인하려는 switch
문에서 특히 유용합니다.
nonNull
nonNull < T > ( value : T | null | undefined ) : value is T
value: T | null | undefined
null
또는 undefined
아닌지 확인하려는 값입니다. value is T
이는 함수가 전달된 값이 null
도 아니고 undefined
도 않은지 여부를 나타내는 부울을 반환한다는 것을 의미합니다. 이는 true
반환될 때 value
유형을 T
로 좁힙니다(즉, null
및 undefined
제외). nonNull
은 지정된 값이 null이 아닌지, 즉 null
도 undefined
도 아닌지 확인하는 조건자 함수입니다. 함수를 호출한 후 true
또는 false
반환되었는지에 따라 value
유형이 적절하게 좁아집니다.
nonNull
잠재적으로 null
, undefined
또는 둘 다일 수 있는 값이 있고 이를 확인하고 해당 유형을 적절하게 좁히고 싶을 때마다 사용해야 합니다.
이 함수의 이름은 유형에서 null
및 undefined
제외하는 NonNullable
유틸리티 유형에서 유래되었습니다.
declare const names : ( string | null ) [ ] ;
const nonNullNames = names . filter ( nonNull ) ;
// nonNullNames has type 'string[]'
이 예에는 일부 null
요소도 포함할 수 있는 이름 배열이 있습니다. null이 아닌 모든 요소에 대해 배열을 필터링하고 string[]
반환합니다.
대신 names.filter(x => x !== null)
사용하면 null이 아닌 요소를 반환하지만 TypeScript는 filter
에 전달한 함수를 확인하므로 유형은 여전히 (string | null)[]
입니다. 단지 boolean
을 반환하므로 유형 축소가 발생하지 않습니다.
invariant
으로 전달된 message
인수를 제거하고 프로덕션에서 warning
호출을 완전히 제거하려면 babel-plugin-dev-expression
사용하는 것이 좋습니다.
기본적으로 프로덕션에서는 babel-plugin-dev-expression
대체됩니다.
invariant ( value , 'Value is falsy!' ) ;
~와 함께
if ( ! value ) {
invariant ( false ) ;
}
따라서 message
인수가 제거됩니다. 또한 warning
호출을 완전히 제거합니다. 그래서 이런 라인이
warning ( value , 'Value is falsy!' ) ;
제거됩니다.
끌어오기 요청은 매우 환영합니다. 큰 변화를 도입하려는 경우 먼저 관련 이슈를 열어서 무엇을 변경하고 싶은지 논의할 수 있습니다.
테스트와 README를 적절하게 업데이트하세요.
MIT