기능 매개 변수의 유형을 설정 하시겠습니까?


161

특정 매개 변수가 특정 유형임을 Javascript 함수에 알리는 방법이 있습니까?

이와 같은 것을 할 수 있다면 완벽 할 것입니다.

function myFunction(Date myDate, String myString)
{
    //do stuff
}

감사합니다!

업데이트 : 대답이 울리는 "아니오"이기 때문에 myDate(날짜 함수를 호출하기 위해) 날짜로 취급하려면 함수 내에서 날짜로 캐스팅하거나 새 변수를 설정해야합니다. 날짜를 입력 하시겠습니까?


1
기본적이고 일반적인 의미가 아닙니다. 이 작업을 직접 할 수는 있지만 "특정 유형"을 정의하는 방법에 따라 다릅니다.
— hugomg

2
JavaScript에는 클래스가 없으므로 Date, 클래스 만 없습니다 object.
— 제거

@Radu : 이 Mozilla Develop Network 페이지는 어떻습니까?
— dmr

@dmr, 그건 수업이 아닙니다. Date함수입니다. 한 번 봐 가지고 stackoverflow.com/questions/1646698/...를 자바 스크립트에 대한 자세한 내용을 보려면하는 new키워드를. 또한 클래스가 없으므로 캐스팅이 없습니다. 원하는 기능을 간단히 호출 할 수 있습니다. 개체에 개체가 포함되어 있으면 개체가 실행되고 그렇지 않으면 오류가 발생합니다.
— 제거

2
그것은 오래된 것이지만 아무도 언급하지 않은 typescript
— kit

답변:


180

아니요, JavaScript는 정적으로 유형이 지정된 언어가 아닙니다. 때로는 함수 본문에서 매개 변수 유형을 수동으로 확인해야 할 수도 있습니다.


180
축복과 저주.
— Jeffrey Sweeney

40
@JeffreySweeney는 PHP가 정적으로 타입이 아닙니다. 그러나 PHP에서 유형 힌트를 수행하는 옵션이 있습니다. 큰 nodejs 백엔드 응용 프로그램 을 본 적이 있습니까? 정확히, 각 함수에는 인수가 있으며 각 인수가 무엇인지 전혀 알 수 없습니다. 우리는 수천 가지 논쟁에 대해 이야기하고 있으며 읽을 때 전체 코드와 발신자와 발신자의 코드 전체를 읽어야합니다. 축복? 당신은 확실히 jesting해야합니다.
— Toskan

14
타입 힌트를 축복하는 것을 허용하지 않는 기능을 호출하는 사람을 강타하는 것 외에도 typescript를 지적하고 싶을 수도 있습니다. typescriptlang.org 기본적으로 EM6 + 타입 힌트
— Toskan

23
@JeffreySweeney 축복이 아닙니다. 암입니다.
— Robo Robok

1
@ Toskan 나는 그것이 축복이 아니라고 말하지 않을 것입니다. 나는 4 년 동안 JavaScript를 사용해 왔는데, 이는 일부 언어의 본질입니다. 프로그래밍 언어의 세트는 해야 약하게 강력하게 높은 수준의 낮은 수준에 이르기까지 다양합니다 같은 방식으로 입력하는 입력 이르기까지 다양합니다. 또한 JavaScript는이 를 지원하기 위해 instanceof및 typeof키워드를 제공합니다 . 이것은 더 많은 코드를 필요로하지만, 유형에 크게 의존하는 언어로 JavaScript를 선택하는 것은 개발자에게 있습니다. 거대한 nodejs 백엔드 애플리케이션은? 나는 상식이어야한다고 생각합니다.
— Marvin

82

자바 스크립트는 아니지만 Google Closure Compiler의 고급 모드를 사용하면 다음과 같이 할 수 있습니다.

/**
 * @param {Date} myDate The date
 * @param {string} myString The string
 */
function myFunction(myDate, myString)
{
    //do stuff
}

http://code.google.com/closure/compiler/docs/js-for-compiler.html을 참조하십시오 .


1
또한 Eclipse JavaScript Editor - Outline View 및 Code Completion 과 함께 작동 / 활성화 합니다. 반면 foo( /*MyType*/ param ): 여기에 설명 된 방법은 또한 작동 stackoverflow.com/a/31420719/1915920
— 안드레아스 디트리히

나는이 질문이 몇 살인지 알고 있지만 IntelliJ에서 영광이라는 것을 지적하고 싶었습니다. 여기에 매우 과소 답변이 있습니다.
— ChettDM

67

JavaScript 에 유형에 대한 언어를 알 수는 없지만 IDE에 유형에 대해 알릴 수 있으므로 훨씬 더 유용한 자동 완성을 얻을 수 있습니다.

이를 수행하는 두 가지 방법이 있습니다.

  1. 주석에 JavaScript 코드를 문서화하는 시스템 인 JSDoc을 사용하십시오 . 특히 @param지시어 가 필요합니다 .

    /**
     * @param {Date} myDate - The date
     * @param {string} myString - The string
     */
    function myFunction(myDate, myString) {
      // ...
    }

    JSDoc을 사용하여 사용자 정의 유형 을 정의 하고 @param지시문에 유형 을 지정할 수도 있지만 JSDoc은 유형 검사를 수행하지 않습니다. 문서화 도구 일뿐입니다. 에 JSDoc,보기에 정의 된 유형을 확인하려면 타이프 라이터를 할 수있는, JSDoc 태그를 구문 분석 .

  2. 에서 매개 변수 바로 앞에 유형을 지정하여 유형 힌트를 사용하십시오
    /* comment */.

    WebStorm의 JavaScript 유형 힌트

    이것은 예를 들어 ReactJS 가 사용하는 꽤 광범위한 기술 입니다. 타사 라이브러리로 전달되는 콜백 매개 변수에 매우 편리합니다.

TypeScript

실제 유형 검사의 경우 가장 가까운 솔루션은 JavaScript 의 ( 대부분 ) 수퍼 셋 인 TypeScript를 사용하는 것 입니다. 여기 5 분 타이프 라이터를 .


8
이것을 얻는 방법 VSCode?
— Anand Undavia

2
감사. 비록 이것이 IDE에 달려 있지만. VI를 사용하는데 작동하지 않습니다.
— negrotico19

@ negrotico19 : viIDE가 아닌 지나치게 남용 된 편집기입니다. Excel에서 뮤직 비디오를vi 만들 수있는 것처럼 많은 작업을 수행 할 수 있습니다 . 좋은 생각? 아마 아닙니다. 작업에 적합한 도구를 사용하십시오.
— Dan Dascalescu

23

Facebook 의 새로운 Flow 라이브러리 인 "JavaScript 프로그램에서 유형 오류를 찾기 위해 설계된 정적 유형 검사기"를 확인하십시오.

정의:

/* @flow */
function foo(x: string, y: number): string {
  return x.length * y;
}
foo('Hello', 42);

타입 검사 :

$> flow
hello.js:3:10,21: number
This type is incompatible with
  hello.js:2:37,42: string

그리고 여기에 그것을 실행하는 방법이 있습니다 .


x가 날짜 유형 인 경우 유형 정의를 추가하는 방법은 무엇입니까? 즉 foo (x : Date) : string {}. 이것이 올바른 방법입니까?
— Aakash Sigdel

12

아니요, 대신 필요에 따라 다음과 같은 작업을 수행해야합니다.

function myFunction(myDate, myString) {
  if(arguments.length > 1 && typeof(Date.parse(myDate)) == "number" && typeof(myString) == "string") {
    //Code here
  }
}

12

당신은 시스템을 구현할 수 있습니다 함수의 래퍼를 사용하여 형식 검사를 자동으로 처리 .

이 접근 방식 declarative type check system을 사용하면 유형 검사를 관리 할 수있는 완전한 빌드 할 수 있습니다 . 이 개념에 대해 더 자세히 살펴보고 싶다면 Functyped 라이브러리를

다음 구현은 단순하지만 작동 가능한 방식으로 주요 아이디어를 보여줍니다 .

/*
 * checkType() : Test the type of the value. If succeds return true, 
 * if fails, throw an Error
 */
function checkType(value,type, i){
  // perform the appropiate test to the passed 
  // value according to the provided type
  switch(type){
    case Boolean : 
      if(typeof value === 'boolean') return true;
      break;
    case String : 
      if(typeof value === 'string') return true;
      break;
    case Number : 
      if(typeof value === 'number') return true;
      break;
    default :
      throw new Error(`TypeError : Unknown type provided in argument ${i+1}`);
  }
  // test didn't succeed , throw error
  throw new Error(`TypeError : Expecting a ${type.name} in argument ${i+1}`);
}


/*
 * typedFunction() : Constructor that returns a wrapper
 * to handle each function call, performing automatic 
 * arguments type checking
 */
function typedFunction( parameterTypes, func ){
  // types definitions and function parameters 
  // count must match
  if(parameterTypes.length !== func.length) throw new Error(`Function has ${func.length} arguments, but type definition has ${parameterTypes.length}`);
  // return the wrapper...
  return function(...args){
    // provided arguments count must match types
    // definitions count
    if(parameterTypes.length !== args.length) throw new Error(`Function expects ${func.length} arguments, instead ${args.length} found.`);
    // iterate each argument value, and perform a
    // type check against it, using the type definitions
    // provided in the construction stage
    for(let i=0; i<args.length;i++) checkType( args[i], parameterTypes[i] , i)
    // if no error has been thrown, type check succeed
    // execute function!
    return func(...args);
  }
}

// Play time! 
// Declare a function that expects 2 Numbers
let myFunc = typedFunction( [ Number, Number ],  (a,b)=>{
  return a+b;
});

// call the function, with an invalid second argument
myFunc(123, '456')
// ERROR! Uncaught Error: TypeError : Expecting a Number in argument 2


11

편집 : 7 년이 지난 후에도이 대답은 여전히 ​​비정기적인 의견을 얻습니다. 런타임 검사를 찾고 있다면 괜찮지 만 Typescript 또는 Flow를 사용하여 컴파일 타임 유형 검사를 권장합니다. 자세한 내용은 위의 https://stackoverflow.com/a/31420719/610585를 참조 하십시오 .

원래 답변 :

언어에 내장되어 있지는 않지만 직접 쉽게 할 수 있습니다. Vibhu의 대답은 Javascript에서 일반적인 유형 검사 방법을 고려할 것입니다. 좀 더 일반화 된 것을 원한다면 다음과 같이 해보십시오.

typedFunction = function(paramsList, f){
    //optionally, ensure that typedFunction is being called properly  -- here's a start:
    if (!(paramsList instanceof Array)) throw Error('invalid argument: paramsList must be an array');

    //the type-checked function
    return function(){
        for(var i=0,p,arg;p=paramsList[i],arg=arguments[i],i<paramsList.length; i++){
            if (typeof p === 'string'){
                if (typeof arg !== p) throw new Error('expected type ' + p + ', got ' + typeof arg);
            }
            else { //function
                if (!(arg instanceof p)) throw new Error('expected type ' + String(p).replace(/\s*\{.*/, '') + ', got ' + typeof arg);
            }
        }
        //type checking passed; call the function itself
        return f.apply(this, arguments);
    }
}

//usage:
var ds = typedFunction([Date, 'string'], function(d, s){
    console.log(d.toDateString(), s.substr(0));
});

ds('notadate', 'test');
//Error: expected type function Date(), got string
ds();
//Error: expected type function Date(), got undefined
ds(new Date(), 42);
//Error: expected type string, got number
ds(new Date(), 'success');
//Fri Jun 14 2013 success

5

ArgueJS 로 쉽게 할 수 있습니다 .

function myFunction ()
{
  arguments = __({myDate: Date, myString: String});
  // do stuff
};

2
훌륭한 도서관처럼 보입니다. 축하합니다.
— FRD

1

사용 typeof또는 instanceof:

const assert = require('assert');

function myFunction(Date myDate, String myString)
{
    assert( typeof(myString) === 'string',  'Error message about incorrect arg type');
    assert( myDate instanceof Date,         'Error message about incorrect arg type');
}

0

어쩌면 이런 도우미 기능 일 수도 있습니다. 그러나 이러한 구문을 정기적으로 사용하고 있다면 Typescript로 전환해야 할 것입니다.

function check(caller_args, ...types) {
    if(!types.every((type, index) => {
        if(typeof type === 'string')
            return typeof caller_args[index] === type
        return caller_args[index] instanceof type;
    })) throw Error("Illegal argument given");
}

function abc(name, id, bla) {
   check(arguments, "string", "number", MyClass)
   // code
}

0

나도 이것에 대해 생각하고있다. C 배경에서 다음과 같은 기능을 사용하여 함수 리턴 코드 유형과 매개 변수 유형을 시뮬레이션 할 수 있습니다.

function top_function() {
    var rc;
    console.log("1st call");
    rc = Number(test_function("number", 1, "string", "my string"));
    console.log("typeof rc: " + typeof rc + "   rc: " + rc);
    console.log("2nd call");
    rc = Number(test_function("number", "a", "string", "my string"));
    console.log("typeof rc: " + typeof rc + "   rc: " + rc);
}
function test_function(parm_type_1, parm_val_1, parm_type_2, parm_val_2) {
    if (typeof parm_val_1 !== parm_type_1) console.log("Parm 1 not correct type");
    if (typeof parm_val_2 !== parm_type_2) console.log("Parm 2 not correct type");
    return parm_val_1;
}

typeof rc = number이지만 값이 NaN 인 두 번째 호출에서 볼 수 있듯이 호출 함수 앞의 Number는 반환 된 실제 값의 유형에 관계없이 Number 유형을 반환합니다.

위의 console.log는 다음과 같습니다.

1st call
typeof rc: number   rc: 1
2nd call
Parm 1 not correct type
typeof rc: number   rc: NaN

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.