npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rbx-safe-types

v1.0.32

Published

A drop-in replacement for rbx-types.

Downloads

13

Readme

ARCHIVED

rbx-safe-types allowed me to iterate over rbx-types ideas much faster and allowed me to experiment and figure out the best ideas for how roblox types should work. Since we have now integrated almost everything I want into rbx-types, I will no longer be maintaining this. I now recommend using the latest rbx-types, which is what I and the roblox-ts team officially support.

Although unrecommended, if you really want to take this idea for yourself, and work on it yourself, you may fork Validark/rbx-safe-types/master.

rbx-safe-types

This is a drop-in replacement for rbx-types.

Installation

Make sure you have the latest version of TypeScript installed by simply running npm i -g typescript.

Run one of the following commands in the directory of your project. Afterwards you will need to reload the window. See the proper command for your system:

Windows

npm i rbx-safe-types & CD node_modules & MOVE /Y rbx-safe-types\include\* rbx-types\include & DEL rbx-types\include\manual.d.ts & RMDIR /Q rbx-safe-types\include & CD .. & echo Installed rbx-safe-types!

MacOS / Any OS with GNU installed

npm i rbx-safe-types & cd node_modules & mv rbx-safe-types/include/* rbx-types/include & rm rbx-types/include/manual.d.ts & rm -r rbx-safe-types/include & CD .. & echo Installed rbx-safe-types!

Restart VSCode by pressing (Ctrl+Shift+P) and selecting Reload Window.

Differences

Here are the reasons I use rbx-safe-types over rbx-types:

  • rbx-safe-types allows type narrowing via ClassName

    const part = {} as Instance;
    
    if (part.IsA("Part")) {
    	// part is: Part | FlagStand | Platform | Seat | SkateboardPlatform | SpawnLocation
    }
    
    if (part.ClassName === "Part") {
    	// part is: Part
    }
  • rbx-safe-types requires explicitness in specifying instance types which are instantiable and superclasses to other types. Consider the following code:

    // in rbx-types, this accepts Script | LocalScript
    // in rbx-safe-types, this accepts only an object for which the ClassName is Script
    function getScriptClassName(script: Script) {
    	return script.ClassName;
    }
    
    // in rbx-types, this accepts StarterPlayerScripts | StarterCharacterScripts
    // in rbx-safe-types, this accepts only an object for which the ClassName is StarterPlayerScripts
    function getObjectClassName(obj: StarterPlayerScripts) {
    	return obj.ClassName;
    }
    
    // in rbx-types this accepts Model | Status | Workspace;
    // in rbx-safe-types, this accepts only an object for which the ClassName is Model
    function getModelClassName(obj: Model) {
    	return obj.ClassName;
    }

    Basically, in rbx-safe-types a Script is ClassName === "Script" and in rbx-types it is IsA("Script"). In other words, in rbx-types a Script is equivalent to rbx-safe-types' Script | LocalScript. The same behavior applies to everything in the InstanceBases interface.

  • rbx-safe-types disallows referencing instances through the dot operator without an explicit definition. This helps avoid name collisions, and can also increases transpiler performance in cases like this. There are two alternatives, shown below:

    const Workspace = game.GetService("Workspace");
    const ReplicatedStorage = game.GetService("ReplicatedStorage");
    
    // bad practice, and disallowed in rbx-safe-types:
    const myPart = Workspace.Maps.Valiant.Houses;
    
    // safer, won't ever have property conflicts, etc.
    const houses = Workspace
    	.FindFirstChild("Maps")!
    	.FindFirstChild("Valiant")!
    	.FindFirstChild("Houses")!;
    
    // Another alternative is using unioned types:
    interface RemotesChildren {
    	Chatted: RemoteEvent;
    	Attacked: RemoteEvent;
    	Usurped: RemoteEvent & {
    		ShouldReplicate: BoolValue;
    	};
    }
    
    const remoteFolder = ReplicatedStorage.WaitForChild("Remotes") as Folder & RemotesChildren;
    print(remoteFolder.Chatted); // exists! Chatted is a RemoteEvent
    print(remoteFolder.Usurped.ShouldReplicate.Value); // TS knows that .Value is a boolean!

    Consider this code, which rbx-types will improperly handle:

    function f(a: Instance) {
    	return a.JobId;
    }
    
    // rbx-types thinks this returns an Instance.
    f(game);
    // rbx-safe-types will give you an error,
    // because your function signature should accept a DataModel instead of an Instance:
    
    function g(a: DataModel) {
    	return a.JobId;
    }
    
    g(game); // works! returns a string

    Any time you have a type which is less specific than the actual instance, you risk running into property-instance name collisions. Thus, rbx-safe-types disallows inferring that accessing non-members are Instance types.

  • rbx-safe-types does not assume that indexing arrays results in defined values.

  • rbx-safe-types pulls documentation from https://developer.roblox.com/api-reference and thus has far more documentation.

  • rbx-safe-types sometimes contains better type information about APIs that return dictionaries. For example, the fields in GetFriendsOnline which may or may not be undefined can be validated by checking the LocationType, which rbx-safe-types has a const enum for. rbx-safe-types also adds an AssetTypeId const enum.

  • rbx-safe-types has full support for BrickColors, and can be used similarly to the ClassName narrowing mentioned above if desired.

  • rbx-safe-types has "real" Roblox Enum object support, meaning one can access EnumItem.Value, EnumItem.Name, and EnumItem.EnumType. However, neither Enum.GetEnums() nor EnumType.GetEnumItems() are supported. EnumItem.Value is recommended for those concerned with efficiency, and EnumItem.Name is obviously better for readability and TypeScript's suggestion prompts.

    • This allows rbx-safe-types to add CastsToEnum<EnumType | EnumItem>, so that TS code can pass strings/numbers into Roblox functions which require Enums. At the moment, we are waiting on a TS update which allow us to permit this behavior on property setting.
    • Goal: At some point I would like to have an optimization built-in to the transpiler to fold Enum.EnumType.EnumItem.Value into a constant.
    • Caveat: As a side effect of TypeScript's type system, if working exclusively with the Enum Objects themselves, you may have to return error("") on an extra branch because TS considers any object that looks like a duck to be a duck. Thus, Enums are not considered immutable by TypeScript, but their Value and Name properties are, because strings and numbers are each immutable.
    • Like Roblox Objects, one should refrain from trying to iterate over their members using a for loop.
  • rbx-safe-types has better information and is more specific about what kind of Instance things are.

  • rbx-safe-types doesn't have a bunch of internal members of Instances which look like: _210: never

  • rbx-safe-types removes 99% of the internal Rbx_ classes. Those that remain now carry the prefix RbxInternal instead to avoid confusion for users.

  • rbx-safe-types has more dank documentation:

AddAccessory docs

(this documentation was copied from this page, but I thought it was particularly funny)