在 TypeScript 类中,可以为属性声明类型,例如:
class className {
property: string;
};
如何在对象文字中声明属性的类型?
我尝试了以下代码,但无法编译:
var obj = {
property: string;
};
我收到以下错误:
当前范围内不存在名称“字符串”
我做错了什么还是这是一个错误?
在 TypeScript 类中,可以为属性声明类型,例如:
class className {
property: string;
};
如何在对象文字中声明属性的类型?
我尝试了以下代码,但无法编译:
var obj = {
property: string;
};
我收到以下错误:
当前范围内不存在名称“字符串”
我做错了什么还是这是一个错误?
你已经很接近了,你只需=
要用:
. 您可以使用对象类型文字(参见规范第 3.5.3 节)或接口。使用对象类型文字接近于您所拥有的:
var obj: { property: string; } = { property: "foo" };
但是你也可以使用一个接口
interface MyObjLayout {
property: string;
}
var obj: MyObjLayout = { property: "foo" };
经过多年使用const
更多功能代码并从中受益后,我建议在大多数情况下不要使用以下代码。(在构建对象时,将类型系统强制为特定类型而不是让它推断类型通常表明存在问题)。
相反,我建议const
尽可能使用变量,然后将对象组合为最后一步:
const id = GetId();
const hasStarted = true;
...
const hasFinished = false;
...
return {hasStarted, hasFinished, id};
如果您确实需要一种可以延迟初始化的类型:将其标记为可为空的联合类型(null 或 Type)。类型系统将阻止您在没有首先确保它具有值的情况下使用它。
在tsconfig.json
中,确保启用严格的空检查:
"strictNullChecks": true
然后使用此模式并允许类型系统保护您免受意外的空/未定义访问:
const state = {
instance: null as null | ApiService,
// OR
// instance: undefined as undefined | ApiService,
};
const useApi = () => {
// If I try to use it here, the type system requires a safe way to access it
// Simple lazy-initialization
const api = state?.instance ?? (state.instance = new ApiService());
api.fun();
// Also here are some ways to only access it if it has value:
// The 'right' way: Typescript 3.7 required
state.instance?.fun();
// Or the old way: If you are stuck before Typescript 3.7
state.instance && state.instance.fun();
// Or the long winded way because the above just feels weird
if (state.instance) { state.instance.fun(); }
// Or the I came from C and can't check for nulls like they are booleans way
if (state.instance != null) { state.instance.fun(); }
// Or the I came from C and can't check for nulls like they are booleans
// AND I was told to always use triple === in javascript even with null checks way
if (state.instance !== null && state.instance !== undefined) { state.instance.fun(); }
};
class ApiService {
fun() {
// Do something useful here
}
}
使用as
TSX 的运算符。
var obj = {
property: null as string
};
一个更长的例子:
var call = {
hasStarted: null as boolean,
hasFinished: null as boolean,
id: null as number,
};
使用强制转换运算符使这个简洁(通过将 null 强制转换为所需的类型)。
var obj = {
property: <string> null
};
一个更长的例子:
var call = {
hasStarted: <boolean> null,
hasFinished: <boolean> null,
id: <number> null,
};
这比有两个部分(一个声明类型,第二个声明默认值)要好得多:
var callVerbose: {
hasStarted: boolean;
hasFinished: boolean;
id: number;
} = {
hasStarted: null,
hasFinished: null,
id: null,
};
我很惊讶没有人提到这一点,但您可以创建一个名为 的接口ObjectLiteral
,它接受key: value
类型对string: any
:
interface ObjectLiteral {
[key: string]: any;
}
然后你会使用它,像这样:
let data: ObjectLiteral = {
hello: "world",
goodbye: 1,
// ...
};
一个额外的好处是您可以根据需要多次重复使用此界面,在您想要的任意数量的对象上。
祝你好运。
您可以使用预定义的实用程序类型Record<Keys, Type>
:
const obj: Record<string, string> = {
property: "value",
};
它允许为您的对象文字指定键:
type Keys = "prop1" | "prop2"
const obj: Record<Keys, string> = {
prop1: "Hello",
prop2: "Aloha",
something: "anything" // TS Error: Type '{ prop1: string; prop2: string; something: string; }' is not assignable to type 'Record<Keys, string>'.
// Object literal may only specify known properties, and 'something' does not exist in type 'Record<Keys, string>'.
};
以及属性值的类型:
type Keys = "prop1" | "prop2"
type Value = "Hello" | "Aloha"
const obj1: Record<Keys, Value> = {
prop1: "Hello",
prop2: "Hey", // TS Error: Type '"Hey"' is not assignable to type 'Value'.
};
如果您尝试编写类型注释,则语法为:
var x: { property: string; } = { property: 'hello' };
如果您尝试编写对象文字,则语法为:
var x = { property: 'hello' };
您的代码试图在值位置使用类型名称。
如果您尝试将类型添加到解构的对象文字中,例如在函数的参数中,则语法为:
function foo({ bar, baz }: { bar: boolean, baz: string }) {
// ...
}
foo({ bar: true, baz: 'lorem ipsum' });
在 TypeScript 中,如果我们声明对象,那么我们将使用以下语法:
[access modifier] variable name : { /* structure of object */ }
例如:
private Object:{ Key1: string, Key2: number }
// Use ..
const Per = {
name: 'HAMZA',
age: 20,
coords: {
tele: '09',
lan: '190'
},
setAge(age: Number): void {
this.age = age;
},
getAge(): Number {
return age;
}
};
const { age, name }: { age: Number; name: String } = Per;
const {
coords: { tele, lan }
}: { coords: { tele: String; lan: String } } = Per;
console.log(Per.getAge());
这就是我在 2021 年使用 TypeScript 4.5 所做的事情:
const sm = {
reg: {} as ServiceWorkerRegistration,
quantum: null as number | null,
currentCacheName: '' as string, // superfluous
badSWTimer: 0 as number, // superfluous
}
对于对象属性,这不仅仅是一个值转换,而且与接口定义的工作方式相同。
更新:我以两个多余的类型为例。也就是说,这些类型可以自动推断,因此不会产生编译器错误。
来源:4.4 游乐场
在您的代码中:
var obj = {
myProp: string;
};
您实际上是在创建一个对象文字并将变量字符串分配给属性 myProp。虽然非常糟糕的做法,但这实际上是有效的 TS 代码(不要使用它!):
var string = 'A string';
var obj = {
property: string
};
但是,您想要的是对象文字是类型化的。这可以通过多种方式实现:
界面:
interface myObj {
property: string;
}
var obj: myObj = { property: "My string" };
键入别名:
type myObjType = {
property: string
};
var obj: myObjType = { property: "My string" };
对象类型文字:
var obj: { property: string; } = { property: "Mystring" };
谨防。这对某些人来说似乎很明显,但类型声明:
const foo: TypeName = {}
与铸造相比不一样as
:
const foo = {} as TypeName
尽管建议在其他答案中使用它。
例子:
谢谢,类型安全!:
const foo: { [K in 'open' | 'closed']: string } = {}
// ERROR: TS2739: Type '{}' is missing the following properties from type '{ open: string; closed: string; }': open, closed
再见,类型安全!:
const foo = {} as { [K in 'open' | 'closed']: string }
// No error
type ObjType = {
property: string;
}
然后您可以使用它来绑定您的对象以仅接受这种类型,如下所示。
const obj: ObjType = {
property: "TypeScript"
}
只是为了扩展@RickLove 的回复......
这很好用,因为您只需要定义无法推断的类型:
const initialState = {
user: undefined as User | undefined,
userLoading: false
};
它转译成这个 js 代码:
const initialState = {
user: undefined,
userLoading: false
};
如果你需要将它提取到一个类型中,你可以这样做:
export type InitState = typeof initialState;
使用 DRY 将对象文字转换为类型
做就是了:
const myObject = {
hello: 'how are you',
hey: 'i am fine thank you'
}
type myObjectType = keyof typeof MyObject
任务完成!