除了<string>外,还给字符串提供一种类型

时间:2018-08-12 20:16:02

标签: typescript tsc typescript3.0

在许多情况下,我有一个接受许多字符串的函数:

export const acceptsManyStrings = (one: string, two: string, three: string) => {
    return one.slice(0,1) + two.slice(0,2) + three.slice(0,3);
}

因为从类型的角度来看,参数是可以互换的,所以我可能会弄错顺序,传递两个而不是一个,或者其他任何一种。

我可以通过某种方式键入每个参数吗?

我能想到的唯一方法是愚蠢的方法,像这样:

export interface OneStr {
  one: string
}

export interface TwoStr {
  two: string
}

export interface ThreeStr {
  three: string
}

然后像这样使用它:

export const acceptsManyStrings = (one: OneStr, two: TwoStr, three: ThreeStr) => {
    return one.one.slice(0,1) + two.two.slice(0,2) + three.three.slice(0,3);
}

但是由于明显的原因,该解决方案不是很理想。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

如果要避免参数顺序错误的可能性,建议您使用一个参数,并将其作为包含所有当前参数作为字段的对象。这样,在调用时,很明显哪个值是哪个参数(这是一种非常常见的Javascript方法):

export const acceptsManyStrings = (o: { one: string, two: string, three: string }) => {
    return o.one.slice(0, 1) + o.two.slice(0, 2) + o.three.slice(0, 3);
}

acceptsManyStrings({ one: "", two:"", three:"" })

或使用解构,您也可以这样做:

export const acceptsManyStrings = ({ one, two, three }: { one: string, two: string, three: string }) => {
  return one.slice(0, 1) + two.slice(0, 2) + three.slice(0, 3);
};

您可以在Typescript类型中创建字符串的子类型,但使用品牌类型不兼容。

// The branded types
type One = string & { readonly isOne: unique symbol };
type Two = string & { readonly isTwo: unique symbol };
type Three = string & { readonly isThree: unique symbol };

// The create branded types functions 
export const createOne = (o: string) => o as One;
export const createTwo = (o: string) => o as Two;
export const createThree = (o: string) => o as Three;  

export const acceptsManyStrings = (one: One, two: Two, three: Three) => {
    return one.slice(0, 1) + two.slice(0, 2) + three.slice(0, 3);
}

acceptsManyStrings(createOne(""), createTwo(""), createThree(""))
acceptsManyStrings( createTwo(""), createOne(""), createThree(""))// error

但是在这种情况下,这可能是矫kill过正

相关问题