TypeScript第二个参数类型基于第一个参数类型

时间:2017-11-03 09:39:34

标签: javascript typescript types enums overloading

我有第一个参数可能值的枚举,我希望第二个参数基于第一个参数。所以,如果给出NAME,我希望第二个参数为字符串。如果给出了AGE,我希望第二个参数是一个数字。

我该怎么办?

enum KeyType {
   NAME,
   AGE
}

class MyClass {
   public static setProperty(key: KeyType.NAME, value: string): void { }
   public static setProperty(key: KeyType.AGE, value: number): void { } 
}

我想把这样的方法称为:
MyClass.setProperty(KeyType.NAME, 'John');

此外,这应该显示错误:
MyClass.setProperty(KeyType.NAME, 5); // 5不是字符串

在此示例中,它不起作用,因为key类型被错误定义(键类型实际上是枚举的值,因此键类型为0)。

我也愿意接受有关使用此功能的不同方法的建议,该功能仅允许特定参数键的特定类型。

5 个答案:

答案 0 :(得分:3)

您希望使用函数重载来使类型检查正常工作:

import { NgModule } from '@angular/core';
import { HttpModule } from '@angular/http';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

import {
  CommonServiceModule
} from '../../lib/index';

const config = { url: 'http://localhost:8090/application'};
const defaultHeaders = { 'applciation-id': 'AP1234' };

@NgModule({
  imports: [
    BrowserModule,
    CommonServiceModule.withConfiguration(defaultHeaders, <any>config),
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
  ]
})
export class AppModule {
}

或更简单,只需使用字符串:

('start' index) + (length of 'value')

当然,您不必在重载中列出文字字符串,您可以将类似字符串分组为类型定义:

enum KeyType {
   NAME,
   AGE
}

class MyClass {
   public static setProperty(key: KeyType.NAME, value: string): void;
   public static setProperty(key: KeyType.AGE, value: number): void;
   public static setProperty(key: KeyType, value: (string | number)): void {}
}

答案 1 :(得分:0)

你可以试试这个

MyClass.setProperty(key: KeyType, value: string |number) {
  // check key type and throw error as appropriate 
}

答案 2 :(得分:0)

我正在使用另一种方法,使用一个对象。

例如:假设我们正在创建一个发送分析数据的函数,因此我们有一个事件名称和有关此事件的有效负载...

enum TEvents {
  productView = 'web/product/view',
  productPutInCart = 'web/product/put-in-cart'
}

type TLogEvent = ({ event, data }:
  {
    event: TEvents.productView,
    payload: {
      productId: number
    }
  } |
  {
    event: TEvents.productPutInCart,
    payload: {
      productId: number,
      amount: number
    }
  }
) => void

const logEvent: TLogEvent = ({ event, data }) => {
  ...

答案 3 :(得分:-1)

javascript只包含对象,所以如果你想使用枚举,只需将它定义为和对象然后调用它:

var enum1 = { SMALL:"asjdh", MEDIUM:2};
console.log(enum1.SMALL)
console.log(enum1.MEDIUM)

答案 4 :(得分:-1)

这种方法怎么样 - 如果你的类有两个属性,如age和name,你的setProperty函数可以获得字符串或年龄,并根据类型赋值给特定属性,例如:

class MyClass {
    public age:number;
    public name:string;

    setProperty(value: string|number) {
        if (typeof value === 'string') {
            this.name = value;
        } else if (typeof value === 'number') {
            this.age = value;
        }
    }
}

let myClass = new MyClass();

myClass.setProperty("John");
console.log(myClass.name);
myClass.setProperty(60);
console.log(myClass.age);

当然使用这个带有两种类型(字符串或数字)值的技巧你可以按照自己的意愿完成:

setProperty(key: string, value: string|number) {
    if (key === 'AGE') {
        this.age = value;
    } else if (key === 'NAME') {
        this.name = value;
    }
}

但在这种情况下,您需要编写更多代码来保护此部分。