0
# Role and Relationship System
1
2
Schema.org Role types for modeling complex relationships between entities with additional context, temporal information, and specific attributes.
3
4
## Capabilities
5
6
### Role Base Type
7
8
The foundation for all role-based relationships in Schema.org.
9
10
```typescript { .api }
11
/**
12
* Represents additional information about a relationship or property.
13
* For example a Role can be used to say that a 'member' role linking
14
* some SportsTeam to a player occurred during a particular time period
15
*/
16
type Role<TContent = never, TProperty extends string = never> =
17
RoleLeaf<TContent, TProperty> | LinkRole<TContent, TProperty> |
18
OrganizationRole<TContent, TProperty> | PerformanceRole<TContent, TProperty>;
19
20
interface RoleBase extends ThingBase {
21
/** The end date and time of the item (in ISO 8601 date format) */
22
endDate?: SchemaValue<Date | DateTime, "endDate">;
23
/** A position played, performed or filled by a person or organization (deprecated, use roleName instead) */
24
namedPosition?: SchemaValue<Text | URL, "namedPosition">;
25
/** A role played, performed or filled by a person or organization */
26
roleName?: SchemaValue<Text | URL, "roleName">;
27
/** The start date and time of the item (in ISO 8601 date format) */
28
startDate?: SchemaValue<Date | DateTime, "startDate">;
29
}
30
```
31
32
### Schema Value System
33
34
The generic type system that enables Role-based relationships throughout Schema.org.
35
36
```typescript { .api }
37
/**
38
* Generic type for Schema.org property values that can be:
39
* - A simple value of type T
40
* - A Role object containing the value with additional context
41
* - An array of either simple values or Role objects
42
*/
43
type SchemaValue<T, TProperty extends string> = T | Role<T, TProperty> |
44
readonly (T | Role<T, TProperty>)[];
45
```
46
47
**Usage Examples:**
48
49
```typescript
50
import type { Role, SchemaValue } from "schema-dts";
51
52
// Simple role with temporal information
53
const employmentRole: Role = {
54
"@type": "Role",
55
roleName: "Software Engineer",
56
startDate: "2020-01-15",
57
endDate: "2023-06-30"
58
};
59
60
// Person with role-based employment relationship
61
const employee: Person = {
62
"@type": "Person",
63
name: "Jane Developer",
64
worksFor: {
65
"@type": "Role",
66
worksFor: {
67
"@type": "Organization",
68
name: "Tech Corporation"
69
},
70
roleName: "Senior Software Engineer",
71
startDate: "2020-01-15",
72
// endDate omitted for current employment
73
}
74
};
75
76
// Property with multiple values including roles
77
const consultant: Person = {
78
"@type": "Person",
79
name: "John Expert",
80
affiliation: [
81
// Simple organizational affiliation
82
{
83
"@type": "Organization",
84
name: "Professional Association"
85
},
86
// Role-based affiliation with additional context
87
{
88
"@type": "Role",
89
affiliation: {
90
"@type": "Organization",
91
name: "Advisory Board Inc."
92
},
93
roleName: "Technical Advisor",
94
startDate: "2023-01-01"
95
}
96
]
97
};
98
```
99
100
### Organization Role Types
101
102
Specialized roles for organizational relationships and hierarchies.
103
104
```typescript { .api }
105
/**
106
* A subclass of Role used to describe roles within organizations
107
*/
108
type OrganizationRole<TContent = never, TProperty extends string = never> =
109
OrganizationRoleLeaf<TContent, TProperty> | EmployeeRole<TContent, TProperty>;
110
111
interface OrganizationRoleBase extends RoleBase {
112
/** A number associated with a role in an organization, for example, the number on an athlete's jersey */
113
numberedPosition?: SchemaValue<Number, "numberedPosition">;
114
}
115
116
/**
117
* A subclass of OrganizationRole used to describe employee relationships
118
*/
119
type EmployeeRole<TContent = never, TProperty extends string = never> =
120
EmployeeRoleLeaf<TContent, TProperty>;
121
122
interface EmployeeRoleBase extends OrganizationRoleBase {
123
/** The base salary of the job or of an employee in an EmployeeRole */
124
baseSalary?: SchemaValue<MonetaryAmount | Number | PriceSpecification, "baseSalary">;
125
/** The currency (coded using ISO 4217) used for the main salary information in this job posting or for this employee */
126
salaryCurrency?: SchemaValue<Text, "salaryCurrency">;
127
}
128
```
129
130
**Usage Examples:**
131
132
```typescript
133
import type { OrganizationRole, EmployeeRole } from "schema-dts";
134
135
// Organization member with specific role
136
const boardMember: Person = {
137
"@type": "Person",
138
name: "Dr. Sarah Board",
139
memberOf: {
140
"@type": "OrganizationRole",
141
memberOf: {
142
"@type": "Organization",
143
name: "Foundation Board"
144
},
145
roleName: "Board Chair",
146
startDate: "2023-01-01",
147
numberedPosition: 1
148
}
149
};
150
151
// Employee with salary information
152
const salariedEmployee: Person = {
153
"@type": "Person",
154
name: "Mike Worker",
155
worksFor: {
156
"@type": "EmployeeRole",
157
worksFor: {
158
"@type": "Organization",
159
name: "Manufacturing Corp"
160
},
161
roleName: "Production Manager",
162
startDate: "2019-03-01",
163
baseSalary: {
164
"@type": "MonetaryAmount",
165
currency: "USD",
166
value: 75000
167
},
168
salaryCurrency: "USD",
169
numberedPosition: 42
170
}
171
};
172
173
// Organization with employee roles
174
const company: Organization = {
175
"@type": "Organization",
176
name: "Innovation Labs",
177
employee: [
178
{
179
"@type": "Person",
180
name: "Alice Lead"
181
},
182
// Employee relationship via Role
183
{
184
"@type": "EmployeeRole",
185
employee: {
186
"@type": "Person",
187
name: "Bob Junior"
188
},
189
roleName: "Junior Developer",
190
startDate: "2024-01-15",
191
baseSalary: {
192
"@type": "MonetaryAmount",
193
currency: "USD",
194
value: 55000
195
}
196
}
197
]
198
};
199
```
200
201
### Performance Role Types
202
203
Roles for creative and performance contexts.
204
205
```typescript { .api }
206
/**
207
* A PerformanceRole is a Role that some entity places with regard to a theatrical performance,
208
* e.g. in a Movie, TVSeries etc.
209
*/
210
type PerformanceRole<TContent = never, TProperty extends string = never> =
211
PerformanceRoleLeaf<TContent, TProperty>;
212
213
interface PerformanceRoleBase extends RoleBase {
214
/** The name of a character played in some acting or performing role, i.e. in a PerformanceRole */
215
characterName?: SchemaValue<Text, "characterName">;
216
}
217
```
218
219
**Usage Examples:**
220
221
```typescript
222
import type { PerformanceRole } from "schema-dts";
223
224
// Movie with cast roles
225
const movie: Movie = {
226
"@type": "Movie",
227
name: "The Great Film",
228
actor: [
229
// Simple actor credit
230
{
231
"@type": "Person",
232
name: "Famous Actor"
233
},
234
// Detailed performance role
235
{
236
"@type": "PerformanceRole",
237
actor: {
238
"@type": "Person",
239
name: "Character Actor"
240
},
241
characterName: "Detective Smith",
242
startDate: "2023-05-01", // filming start
243
endDate: "2023-08-15" // filming end
244
}
245
]
246
};
247
248
// TV series with recurring character
249
const tvSeries: TVSeries = {
250
"@type": "TVSeries",
251
name: "Drama Series",
252
actor: {
253
"@type": "PerformanceRole",
254
actor: {
255
"@type": "Person",
256
name: "Series Regular"
257
},
258
characterName: "Main Character",
259
roleName: "Lead Actor",
260
startDate: "2022-01-01"
261
// No endDate - ongoing role
262
}
263
};
264
265
// Theater performance
266
const play: TheaterEvent = {
267
"@type": "TheaterEvent",
268
name: "Shakespeare's Hamlet",
269
performer: [
270
{
271
"@type": "PerformanceRole",
272
performer: {
273
"@type": "Person",
274
name: "Stage Actor"
275
},
276
characterName: "Hamlet",
277
roleName: "Lead Role"
278
},
279
{
280
"@type": "PerformanceRole",
281
performer: {
282
"@type": "Person",
283
name: "Supporting Actor"
284
},
285
characterName: "Claudius",
286
roleName: "Supporting Role"
287
}
288
]
289
};
290
```
291
292
### Link Role Types
293
294
Roles for web links and URL relationships.
295
296
```typescript { .api }
297
/**
298
* A Role that represents a Web link, e.g. as expressed via the 'url' property.
299
* Its linkRelationship property can indicate URL-based and plain textual link types
300
*/
301
type LinkRole<TContent = never, TProperty extends string = never> =
302
LinkRoleLeaf<TContent, TProperty>;
303
304
interface LinkRoleBase extends RoleBase {
305
/** The language of the content or performance or used in an action */
306
inLanguage?: SchemaValue<Language | Text, "inLanguage">;
307
/** Indicates the relationship type of a Web link */
308
linkRelationship?: SchemaValue<Text, "linkRelationship">;
309
}
310
```
311
312
**Usage Examples:**
313
314
```typescript
315
import type { LinkRole } from "schema-dts";
316
317
// Web page with categorized links
318
const webpage: WebPage = {
319
"@type": "WebPage",
320
name: "Resource Page",
321
url: "https://example.com/resources",
322
// Simple URL references
323
relatedLink: [
324
"https://related-site1.com",
325
"https://related-site2.com"
326
],
327
// Links with relationship context via LinkRole
328
significantLink: [
329
{
330
"@type": "LinkRole",
331
url: "https://official-docs.com",
332
linkRelationship: "documentation",
333
inLanguage: "en"
334
},
335
{
336
"@type": "LinkRole",
337
url: "https://api-reference.com",
338
linkRelationship: "api-documentation",
339
inLanguage: "en"
340
}
341
]
342
};
343
344
// Organization with typed web relationships
345
const organization: Organization = {
346
"@type": "Organization",
347
name: "Tech Company",
348
url: "https://company.com",
349
sameAs: [
350
// Simple social media links
351
"https://twitter.com/company",
352
"https://linkedin.com/company/company",
353
// Categorized links with LinkRole
354
{
355
"@type": "LinkRole",
356
url: "https://github.com/company",
357
linkRelationship: "code-repository"
358
},
359
{
360
"@type": "LinkRole",
361
url: "https://blog.company.com",
362
linkRelationship: "blog",
363
inLanguage: "en"
364
}
365
]
366
};
367
```
368
369
### Complex Role Relationships
370
371
Advanced patterns for modeling intricate relationships.
372
373
```typescript { .api }
374
// Multiple roles can be combined for complex relationships
375
interface ComplexRoleExample {
376
// A person can have multiple organizational roles
377
multipleRoles: Person;
378
// Temporal role progression
379
roleProgression: Person;
380
// Hierarchical role relationships
381
hierarchicalRoles: Organization;
382
}
383
```
384
385
**Usage Examples:**
386
387
```typescript
388
// Person with multiple simultaneous roles
389
const multiRolePerson: Person = {
390
"@type": "Person",
391
name: "Dr. Multi Role",
392
// Multiple organizational affiliations with different roles
393
memberOf: [
394
{
395
"@type": "OrganizationRole",
396
memberOf: {
397
"@type": "Organization",
398
name: "Medical Association"
399
},
400
roleName: "Board Member",
401
startDate: "2020-01-01"
402
},
403
{
404
"@type": "OrganizationRole",
405
memberOf: {
406
"@type": "Organization",
407
name: "Research Institute"
408
},
409
roleName: "Principal Investigator",
410
startDate: "2021-06-01"
411
}
412
],
413
// Work relationship with detailed employment info
414
worksFor: {
415
"@type": "EmployeeRole",
416
worksFor: {
417
"@type": "Organization",
418
name: "University Hospital"
419
},
420
roleName: "Chief of Surgery",
421
startDate: "2018-07-01",
422
baseSalary: {
423
"@type": "MonetaryAmount",
424
currency: "USD",
425
value: 250000
426
}
427
}
428
};
429
430
// Role progression over time
431
const careerProgression: Person = {
432
"@type": "Person",
433
name: "Career Climber",
434
worksFor: [
435
// Previous role
436
{
437
"@type": "EmployeeRole",
438
worksFor: {
439
"@type": "Organization",
440
name: "Startup Inc"
441
},
442
roleName: "Junior Developer",
443
startDate: "2018-01-01",
444
endDate: "2020-12-31",
445
baseSalary: {
446
"@type": "MonetaryAmount",
447
currency: "USD",
448
value: 60000
449
}
450
},
451
// Current role
452
{
453
"@type": "EmployeeRole",
454
worksFor: {
455
"@type": "Organization",
456
name: "Big Tech Corp"
457
},
458
roleName: "Senior Software Architect",
459
startDate: "2021-01-01",
460
baseSalary: {
461
"@type": "MonetaryAmount",
462
currency: "USD",
463
value: 150000
464
}
465
}
466
]
467
};
468
469
// Organization with hierarchical role structure
470
const hierarchicalOrg: Organization = {
471
"@type": "Organization",
472
name: "Corporate Hierarchy",
473
employee: [
474
// CEO role
475
{
476
"@type": "EmployeeRole",
477
employee: {
478
"@type": "Person",
479
name: "Chief Executive"
480
},
481
roleName: "CEO",
482
numberedPosition: 1
483
},
484
// Department head reporting structure
485
{
486
"@type": "EmployeeRole",
487
employee: {
488
"@type": "Person",
489
name: "Tech Director"
490
},
491
roleName: "CTO",
492
numberedPosition: 2,
493
// Could reference reporting relationships
494
startDate: "2020-01-01"
495
}
496
],
497
// Sub-organizations with their own role structures
498
subOrganization: [
499
{
500
"@type": "Organization",
501
name: "Engineering Department",
502
parentOrganization: {
503
"@id": "#corporate-hierarchy"
504
}
505
}
506
]
507
};
508
```
509
510
### Role Validation and Type Safety
511
512
The Role system provides type safety for relationship modeling.
513
514
```typescript { .api }
515
// Generic Role type ensures type safety
516
type SafeRoleUsage = {
517
// Role must match the property it's used with
518
correctUsage: SchemaValue<Organization, "worksFor">;
519
// TypeScript will enforce matching types
520
typeSafeRole: Role<Organization, "worksFor">;
521
};
522
```
523
524
**Key Benefits:**
525
526
1. **Temporal Context**: Roles can specify start and end dates for relationships
527
2. **Additional Properties**: Roles allow adding context like salary, position numbers, character names
528
3. **Type Safety**: Generic Role types ensure property values match their intended types
529
4. **Flexibility**: Properties can accept simple values, Role objects, or arrays of either
530
5. **Rich Relationships**: Enable modeling of complex organizational hierarchies and performance contexts
531
6. **Backward Compatibility**: Simple property values work alongside Role-enhanced relationships