为字符串指定 <string> 以外的类型
Give a string a type besides <string>
在很多情况下,我有一个接受很多字符串的函数:
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);
}
但是由于显而易见的原因,该解决方案并不是最优的。有什么想法吗?
如果您想避免参数顺序错误的可能性,我建议您使用单个参数并将其作为包含所有当前参数作为字段的对象。这样在调用时会很明显哪个值是哪个参数(这是一种很常见的 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
但在这种情况下这可能有点矫枉过正
在很多情况下,我有一个接受很多字符串的函数:
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);
}
但是由于显而易见的原因,该解决方案并不是最优的。有什么想法吗?
如果您想避免参数顺序错误的可能性,我建议您使用单个参数并将其作为包含所有当前参数作为字段的对象。这样在调用时会很明显哪个值是哪个参数(这是一种很常见的 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
但在这种情况下这可能有点矫枉过正