![](/img/trans.png)
[英]How to create an object in Typescript avoiding to initialize GET properties?
[英]How to initialize an array object with extra properties in TypeScript?
我需要创建以下类型的 object:
type ArrayWithA = [number, number, number] & { a: string };
我这样做如下:
const obj : any = [1, 2, 3];
obj.a = "foo";
const arrayWithA : ArrayWithA = obj as ArrayWithA;
问题:有什么更好的方法来完成这个(即不使用any
)?
奖励问题:什么是初始化 object 类型的好方法: type FuncWithA = ((string)=>void) & { a: string }
?
使用Object.assign
!
Object.assign
的返回类型只是其 arguments 类型的交集,因此您可以通过列出它们的部分并立即组合来组合这些混合对象,而不是事后添加额外的属性(这通常需要类型转换,正如你所注意到的)。
因此,对于您的一些示例,您可能会这样做:
type ArrayWithA = [number, number, number] & { a: string };
// Try like so:
// The cast is needed as otherwise it will be inferred as number[].
const obj2 = Object.assign([1, 2, 3] as [number, number, number], {a: "foo"}); // obj2 has type: [number, number, number] & { a: string } and is assignable to ArrayWithA.
// Same for functions!
type FuncWithA = ((arg: string) => void) & { a: string };
const f1 = Object.assign((s: string) => {}, {a: "foo"}) // f1 has type: ((s: string) => void) & { a: string } and is assignable to FuncWithA.
我建议使用Object.assign()
, TypeScript 的标准库将其表示为返回所需形式的交集类型。 有一点问题是,要让编译器仅仅推断出数组文字将是确切类型的元组[number, number, number]
并不容易。 如果您对readonly [number, number, number]
没问题,那么您可以使用const
断言:
type ArrayWithA = readonly [number, number, number] & { a: string };
const arrayWithA: ArrayWithA = Object.assign([1, 2, 3] as const, { a: "foo" });
否则,您可以使用各种技巧:
type ArrayWithA = [number, number, number] & { a: string };
const arr: [number, number, number] = [1, 2, 3]; // annotate extra variable
let arrayWithA: ArrayWithA = Object.assign(arr, { a: "foo" });
// type assertion
arrayWithA = Object.assign([1, 2, 3] as [number, number, number], { a: "foo" });
// helper function
const asTuple = <T extends any[]>(arr: [...T]) => arr;
arrayWithA = Object.assign(asTuple([1, 2, 3]), { a: "foo" });
对于函数,你可以用Object.assign()
做同样的事情:
type FuncWithA = ((x: string) => void) & { a: string }
let funcWithA: FuncWithA = Object.assign(
(x: string) => console.log(x.toUpperCase()),
{ a: "foo" }
);
但是您也可以只使用 function 语句并稍后添加属性,因为 TypeScript 3.1 引入了expando 函数:
function func(x: string) {
console.log(x);
}
func.a = "foo"; // no error
funcWithA = func; // that works
我会 go 类似:
type ArrayWithA = [number, number, number] & { a: string };
namespace ArrayWithA {
export function of(a: string, ...rest: [number, number, number]): ArrayWithA {
const o = rest as ArrayWithA;
o.a = a;
return o;
}
}
const arrayWithA = ArrayWithA.of('a', 1, 2, 3);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.