Question
In TypeScript, class properties can have type annotations like this:
class ClassName {
property: string;
}
How do you declare the type of a property in an object literal?
I tried this:
var obj = {
property: string;
};
but it does not compile. TypeScript reports:
The name 'string' does not exist in the current scope
Am I using the wrong syntax, or is this a TypeScript bug?
Short Answer
By the end of this page, you will understand why property: string works in a class but not inside an object literal, and how to correctly type object literals in TypeScript using type annotations, inline object types, interfaces, and type inference.
Concept
In TypeScript, type annotations and object values use similar-looking syntax, but they appear in different places.
In a class body, this is a type annotation:
class ClassName {
property: string;
}
Here, property is being declared as a class field, and string is its type.
But in an object literal, this syntax means something different:
var obj = {
property: string
};
Inside an object literal, JavaScript expects property to be assigned a value. So TypeScript reads string as if it were a variable name or identifier, not a type. Since no variable named string exists, you get the error.
To type an object literal, you usually annotate the variable, not the property inside the literal value.
Example:
const obj: { property: string } = {
property: "hello"
};
Mental Model
Think of it like this:
- A class definition is like a blueprint, so you describe the shapes and types of parts.
- An object literal is like the actual built item, so you must provide real values.
Blueprint example
class User {
name: string;
}
You are saying: “A User has a name, and that name must be a string.”
Built object example
const user = {
name: "Ada"
};
You are saying: “Here is the actual value for name.”
If you write this:
const user = {
name: string
};
that is like trying to build the object but placing the word string where an actual value should go.
So the rule is:
- Types go in declarations
- Values go in object literals
Syntax and Examples
Correct ways to type an object literal
1. Annotate the variable with an inline object type
const obj: { property: string } = {
property: "hello"
};
This is the most direct equivalent to your class example.
2. Let TypeScript infer the type
const obj = {
property: "hello"
};
TypeScript infers this as:
{ property: string }
This is often enough if the object is simple.
3. Use an interface
interface MyObject {
property: string;
}
const obj: MyObject = {
property: "hello"
};
This is useful when the same object shape is reused in multiple places.
4. Use a type alias
Step by Step Execution
Consider this example:
const obj: { property: string } = {
property: "hello"
};
console.log(obj.property);
Step by step
const obj:starts a variable declaration.{ property: string }defines the expected shape ofobj.- TypeScript now expects
objto be an object with one property namedproperty. - That property must contain a string value.
- The object literal is checked:
{
property: "hello"
}
"hello"is a string, so it matches the required type.console.log(obj.property)is allowed becausepropertyis known to exist.
What if the value is wrong?
: { : } = {
:
};
Real World Use Cases
Object literal typing is used constantly in real TypeScript code.
Configuration objects
const config: { apiUrl: string; timeout: number } = {
apiUrl: "https://api.example.com",
timeout: 5000
};
API payloads
type LoginRequest = {
email: string;
password: string;
};
const request: LoginRequest = {
email: "user@example.com",
password: "secret"
};
Function arguments
function createUser(user: { name: string; age: number }) {
return `${user.name} is ${user.age}`;
}
createUser({ : , : });
Real Codebase Usage
In real projects, developers usually do not write large inline object types everywhere. Instead, they combine a few common patterns.
Reusable interfaces and type aliases
When the same shape appears more than once:
interface User {
id: number;
name: string;
}
const currentUser: User = {
id: 1,
name: "Ava"
};
Function parameter typing
Object literals are often passed directly into functions:
function sendEmail(options: { to: string; subject: string }) {
console.log(options.subject);
}
sendEmail({ to: "a@example.com", subject: "Welcome" });
Validation at boundaries
Developers often type expected object shapes when handling external input:
= {
: ;
: ;
};
Common Mistakes
1. Putting a type where a value should be
Broken code:
const obj = {
property: string
};
Why it fails:
stringis treated as a variable, not a type
Fix:
const obj: { property: string } = {
property: "hello"
};
2. Forgetting to provide an actual value
Broken code:
const obj: { property: string } = {
property:
};
Fix:
const obj: { property: string } = {
property: "hello"
};
3. Giving the wrong value type
Broken code:
: { : } = {
:
};
Comparisons
Class property typing vs object literal typing
| Context | Syntax | Meaning |
|---|---|---|
| Class body | property: string; | Declares a property type |
| Object literal | property: "hello" | Assigns a value |
| Variable annotation | const obj: { property: string } = ... | Declares the object's expected shape |
Interface vs inline object type
| Option | Example | When to use |
|---|---|---|
| Inline type | const obj: { property: string } = ... | Small one-off objects |
Cheat Sheet
// Class property type
class MyClass {
property: string;
}
// Object literal with inferred type
const obj1 = {
property: "hello"
};
// Object literal with inline type annotation
const obj2: { property: string } = {
property: "hello"
};
// Object literal using an interface
interface MyObject {
property: string;
}
const obj3: MyObject = {
property: "hello"
};
// Object literal using a type alias
type MyObjectType = {
property: string;
};
const obj4: MyObjectType = {
property: "hello"
};
Rules to remember
property: string;is valid in a type position such as a class, interface, or object type.- Inside an object literal, properties need actual values.
FAQ
Why does property: string work in a class but not in an object literal?
Because a class body is a type declaration context, while an object literal is a value context. In an object literal, TypeScript expects a real value after the colon.
How do I type an object literal in TypeScript?
Usually by typing the variable:
const obj: { property: string } = { property: "hello" };
Can TypeScript infer the type automatically?
Yes. If you write:
const obj = { property: "hello" };
TypeScript infers property as a string.
Should I use an interface or an inline object type?
Use an inline type for small one-off cases. Use an interface or type alias when the shape is reused or becomes large.
Is this a TypeScript bug?
No. The syntax is being interpreted correctly. The problem is that string is being used where a value is required.
Can I type individual properties directly inside an object literal value?
Not with property: string syntax. You define the object's type outside the value, or let TypeScript infer it.
Mini Project
Description
Build a small typed configuration object for an application. This demonstrates how to define the shape of an object literal correctly and how TypeScript checks each property value.
Goal
Create a TypeScript configuration object with explicit property types and use it in a function.
Requirements
- Create a type or interface for an app configuration object.
- The configuration must include a
appNamestring, aportnumber, and adebugboolean. - Create an object literal that matches that type.
- Write a function that accepts the configuration object and prints a message using its properties.
Keep learning
Related questions
@Directive vs @Component in Angular: Differences, Use Cases, and When to Use Each
Learn the difference between @Directive and @Component in Angular, including use cases, examples, and when to choose each.
Angular (change) vs (ngModelChange): What’s the Difference?
Learn the difference between Angular (change) and (ngModelChange), when each fires, and which one to use in forms and inputs.
Angular Dependency Injection: Fix "Can't Resolve All Parameters for Component" Errors
Learn why Angular shows "Can't resolve all parameters for component" and how to fix service injection issues in components.