Typescript Definition - 如何在接受某些字符串的对象中定义数组属性

时间:2018-01-21 02:57:11

标签: typescript

我需要定义一个包含字符串数组的对象,但该字符串只能接受某些值。以下示例是可能的情况:

let user = {
   name: 'John',
   communicationPreferences: ['email', 'whatsApp']
}

let user = {
   name: 'John',
   communicationPreferences: ['whatsApp', 'weChat', 'skype']
}

 let user = {
   name: 'John',
   communicationPreferences: ['email', 'whatsApp', 'weChat', 'skype', 'line', 'sms']
 }

4 个答案:

答案 0 :(得分:1)

根据您的具体情况,您有一些选择:

Enum :提供灵活的,类型安全的值定义,允许运行时查找和反向查找。这可能是您首选的解决方案:

enum Channel {
    Email = 'email', // if you prefer email = 'email', etc. that's also very doable
    WhatsApp = 'whatsApp',
    WeChat = 'weChat',
    Skype = 'skype',
    Line = 'line',
    SMS = 'sms',
}

class User {
   constructor(private name: string, private communicationPreferences: Channel[]) { };
}

const john = new User('john', [Channel.SMS]); // {name: 'john', communicationPreferences: ['sms']);

// example of reverse look-up
const channel = 'skype'; // from some unverified source
if (Channel[channel] === undefined) {
   // handle error case at run-time
}

联盟类型:如果您想快速而肮脏,可以使用string literal union type。这将只提供编译时安全性,或者如果你有一个非常极端的情况,你想限制枚举的(非常小的)开销:

type Channel = 'email'| 'whatsApp'| 'weChat' | 'skype' | 'line'| 'sms';

interface User {
   name: string;
   communicationPreferences: Channel[];
}

const john: User = {
    name: 'john',
    communicationPreferences: ['telegraph']; // would fail to compile
}

索引类型:您的最后一个选项是组合keyof and typeof运算符以生成动态联合类型。如果您的通信通道选项来自外部JSON / JS文件,这可能很有用,特别是如果它可能会更改:

// Some example object you're getting

const channels = {
   skype: { ... },
   sms: { ... },
   line: { ... },
   // and so on
}

// in your script
type Channel = keyof typeof channels; // "skype" | "sms" | "line" | ...

在您的情况下,您可能也对Set课感兴趣;它提供了一个独特的(每个允许的值中只有一个)集合:

// define Channel type, from options above

class User {
    private communicationPreferences: Set<Channel>;

    constructor(private name: string, channels: Channel[]) {
        this.communicatonPreferences = new Set<Channel>(channels);
    }

    public serialize() {
        return {
            name: this.name,
            communicationPreferences: Array.from(this.communicationPreferences)
        }
    }
}

答案 1 :(得分:0)

Typescript允许使用Enum:

export enum communicationPreferences{
whatsApp=0
weChat=1
skype=2
}

var value: communicationPreferences=communicationPreferences[communicationPreferences.whatsApp]

要小心尝试使用communicationPreferences.whatsApp之类的东西,它会返回整数值。

似乎打字稿2.4现在支持基于字符串的枚举,所以我们甚至不需要做整数的东西,只需声明whatsApp =&#34; whatsApp&#34;

答案 2 :(得分:0)

为了达到这个目的,我将使用Enums构建一个强类型对象:

export enum ChannelCommunication {
        whatsApp = 'whatsApp',
        weChat = 'weChat',
        skype = 'skype',
        email = 'email',
        line = 'line',
        sms = 'sms'
    }

    export class User {

        private _name: String;
        private _communicationPreferences: ChannelCommunication[];

        constructor(name:String, communicationPreferences: Array<ChannelCommunication>) {
            this._name = name;
            this._communicationPreferences = communicationPreferences;
        }
        public name: String;
        public communicationPreferences: ChannelCommunication[]
    }



    let communicationPreferences: ChannelCommunication[] = [ChannelCommunication.email,
 ChannelCommunication.line,
 ChannelCommunication.skype,
 ChannelCommunication.sms,
 ChannelCommunication.weChat,
 ChannelCommunication.whatsApp];

let user = new User('John',communicationPreferences);

希望它能回答你的问题

答案 3 :(得分:0)

type CommunicationPreferences = 'email' | 'whatsApp' | 'weChat' | 'skype' | 'line' | 'sms';

interface User {
    name: string;
    communicationPreferences: CommunicationPreferences[];
}

let user : User = {
    name: 'John',
    communicationPreferences: ['email', 'whatsApp', 'weChat', 'skype', 'line', 'sms']
}