sourcecode

문자열 리터럴 형식 인수를 기반으로 하는 변수 반환 형식

codebag 2023. 6. 12. 21:23
반응형

문자열 리터럴 형식 인수를 기반으로 하는 변수 반환 형식

TypeScript 1.8 또는 2.0에서 문자열 리터럴 형식 인수 값을 기반으로 한 변수 반환 형식을 가질 수 있습니까?

type Fruit = "apple" | "orange" 
function doSomething(foo : Fruit) : string | string[] {
    if (foo == "apple") return "hello";
    else return ["hello","world"];
}

var test : string[] = doSomething("orange");

오류: TS2322: 'string | string[]' 유형은 'string[]' 유형에 할당할 수 없습니다.

예, 오버로드 서명을 사용하여 원하는 작업을 정확히 수행할 수 있습니다.

type Fruit = "apple" | "orange"

function doSomething(foo: "apple"): string;
function doSomething(foo: "orange"): string[];
function doSomething(foo: Fruit): string | string[]
{
    if (foo == "apple") return "hello";
    else return ["hello", "world"];
}

let orange: string[] = doSomething("orange");
let apple: string = doSomething("apple");

할당하는 중doSomething("apple")로.orange컴파일 시간 유형 오류를 생성합니다.

let orange: string[] = doSomething("apple");
 // ^^^^^^
 // type 'string' is not assignable to type 'string[]'

TypeScript Playground의 라이브 데모

어떤 오버로드 서명이 사용되었는지 결정하는 것은 함수 구현에서 항상 수동으로 수행되어야 하며 함수 구현은 모든 오버로드 서명을 지원해야 합니다.

TypeScript에는 C#과 같이 오버로드당 별도의 구현이 없습니다.따라서 런타임에 TypeScript 유형 검사를 강화하는 것이 좋은 방법이라고 생각합니다. 예를 들어 다음과 같습니다.

switch (foo) {
    case "apple":
        return "hello";
    case "orange":
        return ["hello", "world"];
    default:
        throw new TypeError("Invalid string value.");
}

더 나은 접근법이 있습니다.인수 유형으로 사용되는 제네릭을 사용합니다(따라서 제네릭을 수동으로 전달할 필요가 없으며 자동으로 입력 스크립트가 추론합니다).그런 다음 해당 유형을 사용하여 올바른 반품 유형을 선택할 수 있습니다.

type Fruit = 'apple' | 'orange';
function doSomething<P extends Fruit>(foo: P): ({ apple: string; orange: string[] })[P] {
  if (foo === 'apple') return 'hello';
  return ['hello','world];
}
const x: string = doSomething('apple');
const y: string[] = doSomething('orange');

이렇게 하면 자동으로 전달된 인수에 따라 함수의 반환 형식을 변경할 수 있습니다.

네, 가능합니다.테스트만 하면 됩니다.test로 변하기 쉬운.instanceof그러면 유형 스크립트가 유형을 제한합니다.

type Fruit = "apple" | "orange" 
function doSomething(foo: Fruit): string | string[] {
    if (foo == "apple") return "hello";
    else return ["hello","world"]
}

// here the type is still inferred as: string | string[]
var test = doSomething("orange");

if (test instanceof String) {
    // TypeScript knows test is type: string
    doSomethingWithString(test);
} else {
    // TypeScript knows test is type: string[]
    doSomethingWithStringArray(test);
}

function doSomethingWithString(input: string) {}
function doSomethingWithStringArray(input: string[]) {}

갱신하다

대신 메소드를 일반적으로 만드는 것이 좋습니다.

function doSomething<T>(foo: Fruit): T {
    if (foo == "apple") return "hello";
    else return ["hello","world"]
}

var test1 = doSomething<string>("apple");
var test2 = doSomething<string[]>("orange");

또는 다른 옵션은 흐름을 다음과 같은 것으로 전환하는 것입니다.

type Fruit = "apple" | "orange" 
function doSomething(foo: Fruit): void {
    if (foo == "apple") 
        doSomthingWithString("hello");
    else 
        doSomethingWithStringArray(["hello","world"]);
}

function doSomethingWithString(input: string) {}
function doSomethingWithStringArray(input: string[]) {}

갱신하다

사실 저는 화이트의 대답이 훨씬 더 좋다고 생각합니다.

언급URL : https://stackoverflow.com/questions/39700093/variable-return-types-based-on-string-literal-type-argument

반응형