JavaScript에서 완벽한 지능형 인식

일반적으로 TypeScript는 대규모 JavaScript 프로젝트를 쉽게 관리할 수 있는 솔루션으로 설명됩니다.이 주장을 지지하는 논점 중 하나는 유형 정보를 가지고 있으면 범하기 쉽고 발견하기 어려운 많은 실수를 발견하는 데 도움이 된다는 것이다.
TypeScript를 사용하는 것은 항상 선택이 아닐 수도 있습니다. 왜냐하면 오래된 코드 라이브러리를 처리하고 있기 때문입니다. 심지어는 선택입니다.
순수한 JavaScript를 고집하는 이유가 무엇이든지 스마트 감지와 개발 시간 오류가 두드러진 측면에서 거의 같은 개발 체험을 얻을 수 있다.이것이 바로 본문의 주제다.

VS 코드 및 JavaScript intellisence


VS 코드 및 유형 index.js 에 새 conso 을 만들면 다음과 같은 내용이 표시됩니다.

intellisence 데이터의 원본은 VS 코드와 묶인 형식 정의 파일, 즉 컨트롤러가 Ctrl+space에서 정의한 것이다.이 폴더의 모든 확장자 [VS Code installation folder]/code/resources/app/extensions/node_modules/typescript/lib/lib.dom.d.ts 는 인텔리센스 밑에 있는 목록에서 볼 수 있는 내용에 사용됩니다.
TypeScript 정의 파일은 VS 코드의 intellisence 소스 중 하나입니다.
그러나 그것들은 유일한 출처가 아니다.또 다른 출처는 VS 코드가 코드에서 추정한 내용입니다.
다음은 변수를 설명하고 값을 부여하는 예입니다.지능형 감지는 이 값의 유형과 일치합니다.

(예, 노드에서도 문자열에서 .d.ts 또는 .blink() 을 호출할 수 있습니다.js)
다음은 클래스 정의의 변수 사용에서 유형을 추정하는 또 다른 예입니다.

VS 코드는 유형 추정 외에도 편집 중인 파일의 모든 고유 단어를 intellisence 드롭다운 목록에 추가합니다.

비록 VS 코드에서 사용할 수 있는 유형은 매우 똑똑하지만, 그것도 매우 수동적이다..bold() 대신 myInstance.pethodName() 로 전화를 걸면 경고하지 않습니다.

우리는 통상적으로 운행할 때 하나myInstance.methodName()를 얻어야만 이 문제를 해결할 수 있다.
VS 코드에는 기본적으로 닫힌 플래그가 있습니다. 이 플래그가 열리면 형식 검사를 사용하여 코드를 실행하고 오류를 보고합니다.

이 플래그 이름은 TypeError: myInstance.pethodA is not a function 로 불리며 모든 명령 표시 checkJs 를 열고 "작업공간 설정 열기"를 입력한 다음 checkJs 를 활성화하는 가장 간단한 방법입니다.
Ctrl+Shift+p을 열면 파일이 빨간색 크리스마스 트리로 변하는 것을 발견할 수 있을 것이다.그중 일부는 합법적인 잘못일 수도 있지만, 때로는 그렇지 않을 수도 있다.이런 상황은 자주 발생하지 않지만, 나는 자바스크립트 라이브러리의 형식 정의 파일이 최신 버전과 일치하지 않는 상황을 만난 적이 있다. (이 상황의 발생 방식은 잠시 후 블로그 글에서 더욱 명확해질 것이다.)
만약 이러한 상황이 발생하고 코드가 정확하다고 확신한다면 파일의 맨 위에 항상 추가할 수 있습니다.
//@ts-nocheck
이것은 전체 파일의 형식 검사를 닫습니다.한 문장만 무시하려면 무시할 문장 앞에 다음을 추가합니다.
//@ts-ignore
variableThatHoldsANumber = false; //this won't be reported as an error

JavaScript에서 유형 정보 수동 제공


어떤 경우, 유형 추정은 변수에 대한 유형 정보를 찾을 수 없습니다.
예를 들어, REST 노드를 호출하여 주문 목록을 가져오는 경우:
const orders = await getOrdersForClient(clientId);
어떤 유용한 유형의 추측에도 사용할 충분한 정보가 없다.주문 형태는 RESTAPI를 호스팅하는 서버가 우리에게 보내는 내용에 따라 달라집니다.
그러나 우리는 JsDoc 주석을 사용하여 주문서의 외관을 지정할 수 있습니다. 이 주석들은 VS 코드에서 추출하여 스마트 감지를 제공하는 데 사용됩니다.
다음은 주문 상황입니다.
/** @type {Array<{id: string, quantity: number, unitPrice: number, description: string}>} */
const orders = await getOrdersForClient(clientId);
다음은 VS 코드에서 주문에 액세스하는 경우입니다.

비록 이것은 좀 번거로워 보이지만, TypeScript 유형의 정보를 가지고 있는 것은 거의 똑같이 유연하다.또한 필요한 곳에 추가할 수 있습니다.만약 내가 문서가 없는 유류 코드 라이브러리에 익숙하지 않다면, 이런 유형의 checkJs 주석을 추가하는 것은 코드 라이브러리에 익숙해지는 과정에서 매우 도움이 될 것이다.
다음은 JsDoc 유형의 주석을 사용할 수 있는 예입니다.

유형 정의 및 다중 사용


/**
* @typedef {object} MyType
* @property {string} aString
* @property {number} aNumber
* @property {Date} aDate
*/

/** @type {MyType} */
let foo;
/** @type {MyType} */
let bar;
모듈로 된 파일에서 JsDoc (VS 코드가 이 상황을 가정하면 파일에 @typedef 문장만 있으면 다른 파일에서 유형 정보를 가져올 수 있습니다.
예를 들어, exports@typedef 라는 파일에 있고 같은 폴더의 my-type.js 에 입력한 경우
/** @type {import('./my_type').MyType} */
let baz;
another-file.js 변수의 스마트 감지는 baz의 유형 정보를 바탕으로 한다.

함수 매개 변수와 반환값


또 다른 유형은 함수 정의의 매개 변수 유형에 대해 큰 역할을 하지 못할 것으로 추정된다.예:
function send(type, args, onResponse) {
    //...
}
파라미터MyType,type,args에 관해서는 여기서 추정할 수 있는 것이 많지 않다.함수의 반환값도 마찬가지다.
고맙게도 우리는 onResponse 구조로 이 모든 것을 설명할 수 있다. 다음은 JsDoctype 이고, string 는 무엇이든지, args 는 두 개의 매개 변수 onResponseerror 가 있는 선택 가능한 함수이며, 마지막 반환 값은 result 이나 없다.
이것은 상당히 복잡한 예이지만, 우리가 제공할 수 있는 유형 정보는 사실상 제한이 없다는 것을 설명할 수 있다.이것은 보기에 이렇다.
/**
 * You can add a normal comment here and that will show up when calling the function
 * @param {string} type You can add extra info after the params
 * @param {any} args As you type each param you'll see the intellisense updated with this description
 * @param {(error: any, response: any) => void} [onResponse]
 * @returns {Promise<any> | void} You can add extra an description here after returns
 */
function send(type, args, onResponse) {
    //...
}
여기서 이 기능은 다음과 같습니다.

클래스 및 상속


자주 발생하는 일은 다른 클래스로부터 계승된 클래스를 만들어야 한다는 것입니다.때때로 이런 종류는 심지어 템플릿화할 수도 있다.
예를 들어 이것은 React에서 매우 흔히 볼 수 있으며 React에서 클래스 구성 요소의 속성과 상태에 intellisence를 가지는 데 매우 유용하다.다음은 Promise라는 구성 요소에 대해 어떻게 해야 하는지입니다. 이 구성 요소의 상태는 ClickCounter라는 속성입니다. 이 속성은 숫자이고 count라는 문자열 형식의 구성 요소 속성도 있습니다.
/** @extends {React.Component<{message: string}, {count: number}>}  */
export class ClickCounter extends React.Component {
    //this @param jsdoc statement is required if you want intellisense
    //in the ctor, to avoid repetition you can always define a @typedef
    //and reuse the type
    /** @param { {message: string} } props */
    constructor(props) {
        super(props);
        this.state = {
            count: 0,
        }
    }

    render() {
        return (
            <div onClick={_ => this.setState({ count: this.state.count + 1 })}>{this.props.message} - {this.state.count} </div>
        );
    }
}
이것은 구성 요소를 사용할 때의 모양입니다.

이것은 기능 구성 요소에서도 가능하다. 예를 들어 이 기능 구성 요소는 사용에 있어서 상기 예시의 클래스 구성 요소와 같은 스마트 감지를 가진다.
/**
* @param {object} props
* @param {string} props.message
*/
export function ClickCounter(props) {
    const [count, setCount] = useState(0);

    return (
        <div onClick={_ => setCount(count + 1)}>{props.message} - {count} </div>
    );
}

주조


때때로 변수를 특정 유형으로 강제하기를 원할 수 있습니다. 예를 들어 숫자나 문자열일 수 있는 변수가 있다고 가정하면 다음과 같습니다.
if (typeof numberOrString === 'string') {
    //there will be intellisense for substring
    const firstTwoLetters = /** @type {string} */ (numberOrString).substring(0, 2);
}

다른 모듈 유형 정보 사용


노드에서 코드를 작성하고 있다고 가정하십시오.js, 다음과 같은 기능이 있습니다.
function doSomethignWithAReadableStream(stream) {
    //...
}
message 파라미터의 스마트 감지를 읽을 수 있는 흐름으로 사용하기 위해서는 흐름 모듈의 유형 정보가 필요합니다.다음과 같은 가져오기 구문을 사용해야 합니다.
/** @param {import('stream').Readable} stream */
function doSomethindWithAReadableStream(stream) {
    //...
}
그러나 어떤 경우, 가져오려는 유형의 모듈은 이미 사용할 수 없습니다. (흐르는 것처럼)이 경우 DefinitelyTyped 의 형식 정보만 사용하여 npm 패키지를 설치할 수 있습니다.특정 npm 패키지에 필요한 입력 정보를 포함하는 정확한 패키지를 찾기 위한 search tool도 있다.
예를 들어, stream 옵션에 대한 정보를 입력하려면 패키지 유형 정의를 설치해야 합니다.
npm install @types/mocha --save-dev
그리고 mocha 에서 인용하여 옵션의 intellisence를 얻을 수 있습니다.

모듈/패키지 소비자에게 유형 정보 제공


모듈을 만들려면 이 블로그 글에서 본 JsDoc 형식의 주석 공개 함수와 클래스를 사용하십시오. 이 모듈을 다른 모듈에서 사용할 때 스마트 감지를 얻을 수 있습니다.
그러나 형식 정의 파일을 사용하는 대체 방법도 있다.JsDoc라는 파일에 정의된 매우 간단한 모듈CommonJS을 사용한다고 가정하십시오.
function sayHello(greeting) {
    console.log(greeting);
}

module.exports = {
    sayHello
}
say-hello.js라는 파일을 만들고 say-hello.d.ts와 같은 폴더에 배치하면 다음과 같습니다.
export function sayHello(message: string): void;
이 함수를 다른 모듈로 가져오면 say-hello.js 파일에 정의된 입력 정보를 얻을 수 있습니다.
사실 이것은 TypeScript 컴파일러가 .d.ts 로고를 사용하여 컴파일할 때 생성된 파일 형식 .js 입니다.
에피소드로서 자바스크립트로 작성된 npm 모듈을 만들고 여러분과 공유하고 싶다고 가정하십시오.이 밖에 --declaration 형식의 주석은 포함되지 않았지만, 인텔리센스를 제공하기를 원합니다.
일반적으로 JsDoc 또는 index.d.ts 로 명명되고 파일 경로로 설정된 main.d.ts 또는 package.json 속성 업데이트를 사용하여 유형 선언 파일을 만들 수 있습니다.
{
    "name": "the-package-name",
    "author": "Rui",
    "version": "1.0.0",
    "main": "main.js",
    "types": "index.d.ts"
}
types에 입력한 형식 설명은 npm 패키지를 사용할 때 얻을 인텔리센스를 정의합니다.typings의 내용은 모듈의 코드와 일치할 필요가 없다(사실상 index.d.ts 의 유형 정의 패키지는 이렇다).
typescript 정의 파일을 어떻게 작성하는지에 대한 주제를 여기에 두려고 합니다. 이것은 매우 밀집된 주제이기 때문에 대부분의 경우 official docs 에서 유형 정보를 제공하는 방법을 쉽게 찾을 수 있습니다.
TypeScript 정의 파일에 대한 간략한 설명: index.d.ts 파일은 설명된 파일에 영향을 주지 않습니다. 즉, 모듈 DefinitelyTyped 에 형식 설명 파일을 만들고 형식 설명 파일에 .d.ts 형식 my-module.js 의 참수를 지정하고 functionA 내부의 number 에서 이 함수를 호출하면 functionB 의 인텔리센스를 얻을 수 없습니다.유형 선언 파일의 유형 정보는 필요/가져오기my-module 모듈에서만 사용할 수 있습니다.
바로 이렇다. 지금 그 30여 개의 속성의 대형 설정 대상을 생각해 보면 설정할 속성의 정확한 이름functionA이냐, my-module이냐, 필요includeArrayIndex이냐, enableArrayIndex냐를 영원히 기억할 수 없다.지금 너는 타자 실수를 걱정할 필요도, 매번 조사할 필요도 없다.

좋은 웹페이지 즐겨찾기