CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-schema-dts

TypeScript definitions and generator for Schema.org vocabulary with strongly-typed JSON-LD support

Pending
Overview
Eval results
Files

roles-relationships.mddocs/

Role and Relationship System

Schema.org Role types for modeling complex relationships between entities with additional context, temporal information, and specific attributes.

Capabilities

Role Base Type

The foundation for all role-based relationships in Schema.org.

/**
 * Represents additional information about a relationship or property. 
 * For example a Role can be used to say that a 'member' role linking 
 * some SportsTeam to a player occurred during a particular time period
 */
type Role<TContent = never, TProperty extends string = never> = 
  RoleLeaf<TContent, TProperty> | LinkRole<TContent, TProperty> |
  OrganizationRole<TContent, TProperty> | PerformanceRole<TContent, TProperty>;

interface RoleBase extends ThingBase {
  /** The end date and time of the item (in ISO 8601 date format) */
  endDate?: SchemaValue<Date | DateTime, "endDate">;
  /** A position played, performed or filled by a person or organization (deprecated, use roleName instead) */
  namedPosition?: SchemaValue<Text | URL, "namedPosition">;
  /** A role played, performed or filled by a person or organization */
  roleName?: SchemaValue<Text | URL, "roleName">;
  /** The start date and time of the item (in ISO 8601 date format) */
  startDate?: SchemaValue<Date | DateTime, "startDate">;
}

Schema Value System

The generic type system that enables Role-based relationships throughout Schema.org.

/**
 * Generic type for Schema.org property values that can be:
 * - A simple value of type T
 * - A Role object containing the value with additional context
 * - An array of either simple values or Role objects
 */
type SchemaValue<T, TProperty extends string> = T | Role<T, TProperty> | 
  readonly (T | Role<T, TProperty>)[];

Usage Examples:

import type { Role, SchemaValue } from "schema-dts";

// Simple role with temporal information
const employmentRole: Role = {
  "@type": "Role",
  roleName: "Software Engineer",
  startDate: "2020-01-15",
  endDate: "2023-06-30"
};

// Person with role-based employment relationship
const employee: Person = {
  "@type": "Person",
  name: "Jane Developer",
  worksFor: {
    "@type": "Role",
    worksFor: {
      "@type": "Organization",
      name: "Tech Corporation"
    },
    roleName: "Senior Software Engineer",
    startDate: "2020-01-15",
    // endDate omitted for current employment
  }
};

// Property with multiple values including roles
const consultant: Person = {
  "@type": "Person",
  name: "John Expert",
  affiliation: [
    // Simple organizational affiliation
    {
      "@type": "Organization",
      name: "Professional Association"
    },
    // Role-based affiliation with additional context
    {
      "@type": "Role",
      affiliation: {
        "@type": "Organization",
        name: "Advisory Board Inc."
      },
      roleName: "Technical Advisor",
      startDate: "2023-01-01"
    }
  ]
};

Organization Role Types

Specialized roles for organizational relationships and hierarchies.

/**
 * A subclass of Role used to describe roles within organizations
 */
type OrganizationRole<TContent = never, TProperty extends string = never> = 
  OrganizationRoleLeaf<TContent, TProperty> | EmployeeRole<TContent, TProperty>;

interface OrganizationRoleBase extends RoleBase {
  /** A number associated with a role in an organization, for example, the number on an athlete's jersey */
  numberedPosition?: SchemaValue<Number, "numberedPosition">;
}

/**
 * A subclass of OrganizationRole used to describe employee relationships
 */
type EmployeeRole<TContent = never, TProperty extends string = never> = 
  EmployeeRoleLeaf<TContent, TProperty>;

interface EmployeeRoleBase extends OrganizationRoleBase {
  /** The base salary of the job or of an employee in an EmployeeRole */
  baseSalary?: SchemaValue<MonetaryAmount | Number | PriceSpecification, "baseSalary">;
  /** The currency (coded using ISO 4217) used for the main salary information in this job posting or for this employee */
  salaryCurrency?: SchemaValue<Text, "salaryCurrency">;
}

Usage Examples:

import type { OrganizationRole, EmployeeRole } from "schema-dts";

// Organization member with specific role
const boardMember: Person = {
  "@type": "Person",
  name: "Dr. Sarah Board",
  memberOf: {
    "@type": "OrganizationRole",
    memberOf: {
      "@type": "Organization",
      name: "Foundation Board"
    },
    roleName: "Board Chair",
    startDate: "2023-01-01",
    numberedPosition: 1
  }
};

// Employee with salary information
const salariedEmployee: Person = {
  "@type": "Person",
  name: "Mike Worker",
  worksFor: {
    "@type": "EmployeeRole",
    worksFor: {
      "@type": "Organization",
      name: "Manufacturing Corp"
    },
    roleName: "Production Manager",
    startDate: "2019-03-01",
    baseSalary: {
      "@type": "MonetaryAmount",
      currency: "USD",
      value: 75000
    },
    salaryCurrency: "USD",
    numberedPosition: 42
  }
};

// Organization with employee roles
const company: Organization = {
  "@type": "Organization",
  name: "Innovation Labs",
  employee: [
    {
      "@type": "Person",
      name: "Alice Lead"
    },
    // Employee relationship via Role
    {
      "@type": "EmployeeRole",
      employee: {
        "@type": "Person",
        name: "Bob Junior"
      },
      roleName: "Junior Developer",
      startDate: "2024-01-15",
      baseSalary: {
        "@type": "MonetaryAmount",
        currency: "USD",
        value: 55000
      }
    }
  ]
};

Performance Role Types

Roles for creative and performance contexts.

/**
 * A PerformanceRole is a Role that some entity places with regard to a theatrical performance, 
 * e.g. in a Movie, TVSeries etc.
 */
type PerformanceRole<TContent = never, TProperty extends string = never> = 
  PerformanceRoleLeaf<TContent, TProperty>;

interface PerformanceRoleBase extends RoleBase {
  /** The name of a character played in some acting or performing role, i.e. in a PerformanceRole */
  characterName?: SchemaValue<Text, "characterName">;
}

Usage Examples:

import type { PerformanceRole } from "schema-dts";

// Movie with cast roles
const movie: Movie = {
  "@type": "Movie",
  name: "The Great Film",
  actor: [
    // Simple actor credit
    {
      "@type": "Person",
      name: "Famous Actor"
    },
    // Detailed performance role
    {
      "@type": "PerformanceRole",
      actor: {
        "@type": "Person",
        name: "Character Actor"
      },
      characterName: "Detective Smith",
      startDate: "2023-05-01", // filming start
      endDate: "2023-08-15"    // filming end
    }
  ]
};

// TV series with recurring character
const tvSeries: TVSeries = {
  "@type": "TVSeries",
  name: "Drama Series",
  actor: {
    "@type": "PerformanceRole",
    actor: {
      "@type": "Person",
      name: "Series Regular"
    },
    characterName: "Main Character",
    roleName: "Lead Actor",
    startDate: "2022-01-01"
    // No endDate - ongoing role
  }
};

// Theater performance
const play: TheaterEvent = {
  "@type": "TheaterEvent",
  name: "Shakespeare's Hamlet",
  performer: [
    {
      "@type": "PerformanceRole",
      performer: {
        "@type": "Person",
        name: "Stage Actor"
      },
      characterName: "Hamlet",
      roleName: "Lead Role"
    },
    {
      "@type": "PerformanceRole", 
      performer: {
        "@type": "Person",
        name: "Supporting Actor"  
      },
      characterName: "Claudius",
      roleName: "Supporting Role"
    }
  ]
};

Link Role Types

Roles for web links and URL relationships.

/**
 * A Role that represents a Web link, e.g. as expressed via the 'url' property. 
 * Its linkRelationship property can indicate URL-based and plain textual link types
 */
type LinkRole<TContent = never, TProperty extends string = never> = 
  LinkRoleLeaf<TContent, TProperty>;

interface LinkRoleBase extends RoleBase {
  /** The language of the content or performance or used in an action */
  inLanguage?: SchemaValue<Language | Text, "inLanguage">;
  /** Indicates the relationship type of a Web link */
  linkRelationship?: SchemaValue<Text, "linkRelationship">;
}

Usage Examples:

import type { LinkRole } from "schema-dts";

// Web page with categorized links
const webpage: WebPage = {
  "@type": "WebPage",
  name: "Resource Page",
  url: "https://example.com/resources",
  // Simple URL references
  relatedLink: [
    "https://related-site1.com",
    "https://related-site2.com"
  ],
  // Links with relationship context via LinkRole
  significantLink: [
    {
      "@type": "LinkRole",
      url: "https://official-docs.com",
      linkRelationship: "documentation",
      inLanguage: "en"
    },
    {
      "@type": "LinkRole",
      url: "https://api-reference.com",
      linkRelationship: "api-documentation",
      inLanguage: "en"
    }
  ]
};

// Organization with typed web relationships
const organization: Organization = {
  "@type": "Organization",
  name: "Tech Company",
  url: "https://company.com",
  sameAs: [
    // Simple social media links
    "https://twitter.com/company",
    "https://linkedin.com/company/company",
    // Categorized links with LinkRole
    {
      "@type": "LinkRole",
      url: "https://github.com/company",
      linkRelationship: "code-repository"
    },
    {
      "@type": "LinkRole",
      url: "https://blog.company.com",
      linkRelationship: "blog",
      inLanguage: "en"
    }
  ]
};

Complex Role Relationships

Advanced patterns for modeling intricate relationships.

// Multiple roles can be combined for complex relationships
interface ComplexRoleExample {
  // A person can have multiple organizational roles
  multipleRoles: Person;
  // Temporal role progression
  roleProgression: Person;
  // Hierarchical role relationships  
  hierarchicalRoles: Organization;
}

Usage Examples:

// Person with multiple simultaneous roles
const multiRolePerson: Person = {
  "@type": "Person",
  name: "Dr. Multi Role",
  // Multiple organizational affiliations with different roles
  memberOf: [
    {
      "@type": "OrganizationRole",
      memberOf: {
        "@type": "Organization",
        name: "Medical Association"
      },
      roleName: "Board Member",
      startDate: "2020-01-01"
    },
    {
      "@type": "OrganizationRole",
      memberOf: {
        "@type": "Organization", 
        name: "Research Institute"
      },
      roleName: "Principal Investigator",
      startDate: "2021-06-01"
    }
  ],
  // Work relationship with detailed employment info
  worksFor: {
    "@type": "EmployeeRole",
    worksFor: {
      "@type": "Organization",
      name: "University Hospital"
    },
    roleName: "Chief of Surgery",
    startDate: "2018-07-01",
    baseSalary: {
      "@type": "MonetaryAmount",
      currency: "USD",
      value: 250000
    }
  }
};

// Role progression over time
const careerProgression: Person = {
  "@type": "Person",
  name: "Career Climber",
  worksFor: [
    // Previous role
    {
      "@type": "EmployeeRole",
      worksFor: {
        "@type": "Organization",
        name: "Startup Inc"
      },
      roleName: "Junior Developer",
      startDate: "2018-01-01",
      endDate: "2020-12-31",
      baseSalary: {
        "@type": "MonetaryAmount",
        currency: "USD", 
        value: 60000
      }
    },
    // Current role
    {
      "@type": "EmployeeRole",
      worksFor: {
        "@type": "Organization",
        name: "Big Tech Corp"
      },
      roleName: "Senior Software Architect",
      startDate: "2021-01-01",
      baseSalary: {
        "@type": "MonetaryAmount",
        currency: "USD",
        value: 150000
      }
    }
  ]
};

// Organization with hierarchical role structure
const hierarchicalOrg: Organization = {
  "@type": "Organization",
  name: "Corporate Hierarchy",
  employee: [
    // CEO role
    {
      "@type": "EmployeeRole",
      employee: {
        "@type": "Person",
        name: "Chief Executive"
      },
      roleName: "CEO",
      numberedPosition: 1
    },
    // Department head reporting structure
    {
      "@type": "EmployeeRole",
      employee: {
        "@type": "Person",
        name: "Tech Director"
      },
      roleName: "CTO", 
      numberedPosition: 2,
      // Could reference reporting relationships
      startDate: "2020-01-01"
    }
  ],
  // Sub-organizations with their own role structures
  subOrganization: [
    {
      "@type": "Organization",
      name: "Engineering Department",
      parentOrganization: {
        "@id": "#corporate-hierarchy"
      }
    }
  ]
};

Role Validation and Type Safety

The Role system provides type safety for relationship modeling.

// Generic Role type ensures type safety
type SafeRoleUsage = {
  // Role must match the property it's used with
  correctUsage: SchemaValue<Organization, "worksFor">;
  // TypeScript will enforce matching types
  typeSafeRole: Role<Organization, "worksFor">;
};

Key Benefits:

  1. Temporal Context: Roles can specify start and end dates for relationships
  2. Additional Properties: Roles allow adding context like salary, position numbers, character names
  3. Type Safety: Generic Role types ensure property values match their intended types
  4. Flexibility: Properties can accept simple values, Role objects, or arrays of either
  5. Rich Relationships: Enable modeling of complex organizational hierarchies and performance contexts
  6. Backward Compatibility: Simple property values work alongside Role-enhanced relationships

Install with Tessl CLI

npx tessl i tessl/npm-schema-dts

docs

core-types.md

creative-work.md

events.md

index.md

person-organization.md

place-location.md

products-commerce.md

roles-relationships.md

schema-generation.md

tile.json