我希望以与标量值类似的方式初始化传递给函数的对象,例如:
someFunction(myValue: number = 5) { }
所以,我保持两种类型和默认值。我想将类似的结构应用于以下内容:
someFunction(myObj: {val1: number, val2: number}) { }
如果我直接前进并且只是做一些没有脑子的复制粘贴解决方案:
someFunction(myObj: {val1: number = 5, val2: number = 10}) {}
每种初始化方法都会提供TypeScript erorr A type literal property cannot have an initializer.
。好吧,明白了,我无法将类型文字与初始化混合在一起。使用类比,我们有:
someFunction(myValue: number = 5) { }
^^^^^^^ ^^^^^^ ^^
| | +-- Initialization value
| +-- Type literal
+-- Parameter name
类似地:
someFunction(myObj: {val1: number, val2: number} = {val1: 5, val2: 10}) {}
^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^
| | +-- Initialization
| +-- Type literal
+-- Parameter name
解决方案是使用更详细的语法:
someFunction(myObj: {val1: number, val2: number} = {val1: 5, val2: 10}) {}
问题是有可能,有一个蛋糕并吃它:有标量值默认值定义(number = 5)
和带对象定义的完整类型控制的简洁语法?
PS我请求ASCII艺术的奖励积分:)
答案 0 :(得分:1)
没有内置方法可以做到这一点。最简单的解决方案是让编译器根据默认值推断参数类型:
function someFunction(myObj = { val1: 5, val2: 10 }) { }
此解决方案的问题是参数需要所有属性,因此即使它们的值未定义,也必须指定它们。
为了解决这个问题,我们可以定义一个辅助函数,它返回一个所有项都标记为可选的类型:
function params<T>(o: T): Partial<T> {
return o;
}
function someFunction2(myObj = params({ val1: 5, val2: 10, otherValueWithoutDefault: null as number })) { }
或支持可选参数和必需参数的版本:
function params<TRequired>() : <TOptional>(o: TOptional) => Partial<TOptional> & TRequired
function params<TOptional>(o: TOptional) : Partial<TOptional>
function params<T>(o?: T): Partial<T> | (<TOptional>(o: TOptional) => Partial<TOptional> & T) {
if(o != null) {
return o;
} else {
return function(o : any) { return o; } as any
}
}
function someFunction2(myObj = params<{ required: boolean}>()({ val1: 5, val2: 10})) { }
someFunction2({
required: true,
val1: 0
})
答案 1 :(得分:0)
您可以使用界面:
interface myObj {
name: string;
age: number;
anyValue?: any;
}
const someFunction = (myObj: myObj) => {
// method body
};
我希望我理解你的问题并帮助你:) 和mb。这个:https://www.typescriptlang.org/docs/handbook/interfaces.html, 所以使用界面是很好的解决方案。
答案 2 :(得分:0)
如果您利用解构,可以减少大量重复代码,但重要的是要注意这些差异。这是我通常使用的模式。
function fun({ val1 = 1, val2 = 2 } = {}) {
return val1 + val2
}
此功能的签名正确推断为function fun({ val1, val2 }?: { val1?: number; val2?: number; }): number
。
但重要的是要注意,此功能在几个重要方面与原始功能不同。
fun({ val1: 2 })
会导致val2
仍然是默认值,2
如果你需要一个必需的参数(如果你提供任何东西,你必须提供它),你必须回到指定所有东西,由于你在两个位置有初始化器,这很快变得更加混乱。这可以通过使用接口来描述类型来缓解。
interface Args {
val1?: number
val2?: number
val3: string
}
function fun({ val1 = 1, val2 = 2, val3 }: Args = { val3: ' ' }) {
return val3.repeat(val1 + val2)
}