diff --git a/types/node-sass/index.d.ts b/types/node-sass/index.d.ts index b208b57f19..e6d9ad789e 100644 --- a/types/node-sass/index.d.ts +++ b/types/node-sass/index.d.ts @@ -1,56 +1,398 @@ -// Type definitions for Node Sass v3.10.1 +// Type definitions for node-sass 4.11.0 // Project: https://github.com/sass/node-sass -// Definitions by: Asana +// Definitions by: Asana , Chris Eppstein // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 3.0 /// -type ImporterReturnType = { file: string } | { contents: string } | Error | null; +export type ImporterReturnType = { file: string } | { file?: string; contents: string } | Error | null | types.Null | types.Error; -interface Importer { - (url: string, prev: string, done: (data: ImporterReturnType) => void): ImporterReturnType | void; +/** + * The context value is a value that is shared for the duration of a single render. + * The context object is the implicit `this` for importers and sass functions + * that are implemented in javascript. + * + * A render can be detected as asynchronous if the `callback` property is set on the context object. + */ +export interface Context { + options: Options; + callback: SassRenderCallback | undefined; + [data: string]: any; } -interface Options { - file?: string; - data?: string; - importer?: Importer | Importer[]; - functions?: { [key: string]: Function }; - includePaths?: string[]; - indentedSyntax?: boolean; - indentType?: string; - indentWidth?: number; - linefeed?: string; - omitSourceMapUrl?: boolean; - outFile?: string; - outputStyle?: "compact" | "compressed" | "expanded" | "nested"; - precision?: number; - sourceComments?: boolean; - sourceMap?: boolean | string; - sourceMapContents?: boolean; - sourceMapEmbed?: boolean; - sourceMapRoot?: string; +export interface AsyncContext extends Context { + callback: SassRenderCallback; } -interface SassError extends Error { - message: string; - line: number; - column: number; - status: number; - file: string; +export interface SyncContext extends Context { + callback: undefined; } -interface Result { - css: Buffer; - map: Buffer; - stats: { - entry: string; - start: number; - end: number; - duration: number; - includedFiles: string[]; - } +export type AsyncImporter = (this: AsyncContext, url: string, prev: string, done: (data: ImporterReturnType) => void) => void; +export type SyncImporter = (this: SyncContext, url: string, prev: string) => ImporterReturnType; +export type Importer = AsyncImporter | SyncImporter; + +// These function types enumerate up to 6 js arguments. More than that will be incorrectly marked by the compiler as an error. + +// ** Sync Sass functions receiving fixed # of arguments *** +export type SyncSassFn = (this: SyncContext, ...$args: Array) => types.ReturnValue; + +// ** Sync Sass functions receiving variable # of arguments *** +export type SyncSassVarArgFn1 = (this: SyncContext, $arg1: Array) => types.ReturnValue; +export type SyncSassVarArgFn2 = (this: SyncContext, $arg1: types.Value, $arg2: Array) => types.ReturnValue; +export type SyncSassVarArgFn3 = (this: SyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: Array) => types.ReturnValue; +export type SyncSassVarArgFn4 = (this: SyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: types.Value, $arg4: Array) => types.ReturnValue; +export type SyncSassVarArgFn5 = (this: SyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: types.Value, $arg4: types.Value, $arg5: Array) => types.ReturnValue; +export type SyncSassVarArgFn6 = (this: SyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: types.Value, $arg4: types.Value, $arg5: types.Value, $arg6: Array) => types.ReturnValue; + +export type SassFunctionCallback = ($result: types.ReturnValue) => void; + +// ** Async Sass functions receiving fixed # of arguments *** +export type AsyncSassFn0 = (this: AsyncContext, cb: SassFunctionCallback) => void; +export type AsyncSassFn1 = (this: AsyncContext, $arg1: types.Value, cb: SassFunctionCallback) => void; +export type AsyncSassFn2 = (this: AsyncContext, $arg1: types.Value, $arg2: types.Value, cb: SassFunctionCallback) => void; +export type AsyncSassFn3 = (this: AsyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: types.Value, cb: SassFunctionCallback) => void; +export type AsyncSassFn4 = (this: AsyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: types.Value, $arg4: types.Value, cb: SassFunctionCallback) => void; +export type AsyncSassFn5 = (this: AsyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: types.Value, $arg4: types.Value, $arg5: types.Value, cb: SassFunctionCallback) => void; +export type AsyncSassFn6 = (this: AsyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: types.Value, $arg4: types.Value, $arg5: types.Value, $arg6: types.Value, cb: SassFunctionCallback) => void; + +// *** Async Sass Functions receiving variable # of arguments *** +export type AsyncSassVarArgFn1 = (this: AsyncContext, $arg1: Array, cb: SassFunctionCallback) => void; +export type AsyncSassVarArgFn2 = (this: AsyncContext, $arg1: types.Value, $arg2: Array, cb: SassFunctionCallback) => void; +export type AsyncSassVarArgFn3 = (this: AsyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: Array, cb: SassFunctionCallback) => void; +export type AsyncSassVarArgFn4 = (this: AsyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: types.Value, $arg4: Array, cb: SassFunctionCallback) => void; +export type AsyncSassVarArgFn5 = (this: AsyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: types.Value, $arg4: types.Value, $arg5: Array, cb: SassFunctionCallback) => void; +export type AsyncSassVarArgFn6 = (this: AsyncContext, $arg1: types.Value, $arg2: types.Value, $arg3: types.Value, $arg4: types.Value, $arg5: types.Value, $arg6: Array, cb: SassFunctionCallback) => void; + +export type SyncSassFunction = SyncSassFn | SyncSassVarArgFn1 | SyncSassVarArgFn2 | SyncSassVarArgFn3 | SyncSassVarArgFn4 | SyncSassVarArgFn5 | SyncSassVarArgFn6; + +export type AsyncSassFunction = AsyncSassFn0 | AsyncSassFn1 | AsyncSassFn2 | AsyncSassFn3 | AsyncSassFn4 | AsyncSassFn5 | AsyncSassFn6 + | AsyncSassVarArgFn1 | AsyncSassVarArgFn2 | AsyncSassVarArgFn3 | AsyncSassVarArgFn4 | AsyncSassVarArgFn5 | AsyncSassVarArgFn6; + +export type SassFunction = SyncSassFunction | AsyncSassFunction; + +export type FunctionDeclarations = Record; + +export interface Options { + file?: string; + data?: string; + importer?: Importer | Array; + functions?: FunctionDeclarations; + includePaths?: Array; + indentedSyntax?: boolean; + indentType?: string; + indentWidth?: number; + linefeed?: string; + omitSourceMapUrl?: boolean; + outFile?: string; + outputStyle?: "compact" | "compressed" | "expanded" | "nested"; + precision?: number; + sourceComments?: boolean; + sourceMap?: boolean | string; + sourceMapContents?: boolean; + sourceMapEmbed?: boolean; + sourceMapRoot?: string; + [key: string]: any; } -export declare function render(options: Options, callback: (err: SassError, result: Result) => any): void; -export declare function renderSync(options: Options): Result; +export interface SyncOptions extends Options { + functions?: FunctionDeclarations; + importer?: SyncImporter | Array; +} + +/** + * The error object returned to javascript by sass's render methods. + * + * This is not the same thing as types.Error. + */ +export interface SassError extends Error { + message: string; + line: number; + column: number; + status: number; + file: string; +} + +/** + * The result of successfully compiling a Sass file. + */ +export interface Result { + css: Buffer; + map: Buffer; + stats: { + entry: string; + start: number; + end: number; + duration: number; + includedFiles: Array; + }; +} +export type SassRenderCallback = (err: SassError, result: Result) => unknown; + +export namespace types { + /* eslint-disable @typescript-eslint/ban-types */ + /** + * Values that are received from Sass as an argument to a javascript function. + */ + export type Value = Null | Number | String | Color | Boolean | List | Map; + + /** + * Values that are legal to return to Sass from a javascript function. + */ + export type ReturnValue = Value | Error; + + // *** Sass Null *** + + export interface Null { + /** + * This property doesn't exist, but its presence forces the typescript + * compiler to properly type check this type. Without it, it seems to + * allow things that aren't types.Null to match it in case statements and + * assignments. + */ + readonly ___NULL___: unique symbol; + } + + interface NullConstructor { + (): Null; + NULL: Null; + } + export const Null: NullConstructor; + + // *** Sass Number *** + + export interface Number { + getValue(): number; + setValue(n: number): void; + getUnit(): string; + setUnit(u: string): void; + } + interface NumberConstructor { + /** + * Constructs a new Sass number. Does not require use of the `new` keyword. + */ + new(value: number, unit?: string): Number; + /** + * Constructs a new Sass number. Can also be used with the `new` keyword. + */ + (value: number, unit?: string): Number; + } + + export const Number: NumberConstructor; + + // *** Sass String *** + + export interface String { + getValue(): string; + setValue(s: string): void; + } + + interface StringConstructor { + /** + * Constructs a new Sass string. Does not require use of the `new` keyword. + */ + new (value: string): String; + /** + * Constructs a new Sass string. Can also be used with the `new` keyword. + */ + (value: string): String; + } + + export const String: StringConstructor; + + // *** Sass Color *** + + export interface Color { + /** + * Get the red component of the color. + * @returns integer between 0 and 255 inclusive; + */ + getR(): number; + /** + * Set the red component of the color. + * @returns integer between 0 and 255 inclusive; + */ + setR(r: number): void; + /** + * Get the green component of the color. + * @returns integer between 0 and 255 inclusive; + */ + getG(): number; + /** + * Set the green component of the color. + * @param g integer between 0 and 255 inclusive; + */ + setG(g: number): void; + /** + * Get the blue component of the color. + * @returns integer between 0 and 255 inclusive; + */ + getB(): number; + /** + * Set the blue component of the color. + * @param b integer between 0 and 255 inclusive; + */ + setB(b: number): void; + /** + * Get the alpha transparency component of the color. + * @returns number between 0 and 1 inclusive; + */ + getA(): number; + /** + * Set the alpha component of the color. + * @param a number between 0 and 1 inclusive; + */ + setA(a: number): void; + } + + interface ColorConstructor { + /** + * Constructs a new Sass color given the RGBA component values. Do not invoke with the `new` keyword. + * + * @param r integer 0-255 inclusive + * @param g integer 0-255 inclusive + * @param b integer 0-255 inclusive + * @param [a] float 0 - 1 inclusive + * @returns a SassColor instance. + */ + new (r: number, g: number, b: number, a?: number): Color; + + /** + * Constructs a new Sass color given a 4 byte number. Do not invoke with the `new` keyword. + * + * If a single number is passed it is assumed to be a number that contains + * all the components which are extracted using bitmasks and bitshifting. + * + * @param hexN A number that is usually written in hexadecimal form. E.g. 0xff0088cc. + * @returns a Sass Color instance. + * @example + * // Comparison with byte array manipulation + * let a = new ArrayBuffer(4); + * let hexN = 0xCCFF0088; // 0xAARRGGBB + * let a32 = new Uint32Array(a); // Uint32Array [ 0 ] + * a32[0] = hexN; + * let a8 = new Uint8Array(a); // Uint8Array [ 136, 0, 255, 204 ] + * let componentBytes = [a8[2], a8[1], a8[0], a8[3] / 255] // [ 136, 0, 255, 0.8 ] + * let c = sass.types.Color(hexN); + * let components = [c.getR(), c.getG(), c.getR(), c.getA()] // [ 136, 0, 255, 0.8 ] + * assert.deepEqual(componentBytes, components); // does not raise. + */ + new (hexN: number): Color; + + /** + * Constructs a new Sass color given the RGBA component values. Do not invoke with the `new` keyword. + * + * @param r integer 0-255 inclusive + * @param g integer 0-255 inclusive + * @param b integer 0-255 inclusive + * @param [a] float 0 - 1 inclusive + * @returns a SassColor instance. + */ + (r: number, g: number, b: number, a?: number): Color; + + /** + * Constructs a new Sass color given a 4 byte number. Do not invoke with the `new` keyword. + * + * If a single number is passed it is assumed to be a number that contains + * all the components which are extracted using bitmasks and bitshifting. + * + * @param hexN A number that is usually written in hexadecimal form. E.g. 0xff0088cc. + * @returns a Sass Color instance. + * @example + * // Comparison with byte array manipulation + * let a = new ArrayBuffer(4); + * let hexN = 0xCCFF0088; // 0xAARRGGBB + * let a32 = new Uint32Array(a); // Uint32Array [ 0 ] + * a32[0] = hexN; + * let a8 = new Uint8Array(a); // Uint8Array [ 136, 0, 255, 204 ] + * let componentBytes = [a8[2], a8[1], a8[0], a8[3] / 255] // [ 136, 0, 255, 0.8 ] + * let c = sass.types.Color(hexN); + * let components = [c.getR(), c.getG(), c.getR(), c.getA()] // [ 136, 0, 255, 0.8 ] + * assert.deepEqual(componentBytes, components); // does not raise. + */ + (hexN: number): Color; + } + + export const Color: ColorConstructor; + + // *** Sass Boolean *** + + export interface Boolean { + getValue(): boolean; + } + + interface BooleanConstructor { + (bool: boolean): Boolean; + TRUE: Boolean; + FALSE: Boolean; + } + + export const Boolean: BooleanConstructor; + + // *** Sass List *** + + export interface Enumerable { + getValue(index: number): Value; + setValue(index: number, value: Value): void; + getLength(): number; + } + + export interface List extends Enumerable { + getSeparator(): boolean; + setSeparator(isComma: boolean): void; + } + interface ListConstructor { + new (length: number, commaSeparator?: boolean): List; + (length: number, commaSeparator?: boolean): List; + } + export const List: ListConstructor; + + // *** Sass Map *** + + export interface Map extends Enumerable { + getKey(index: number): Value; + setKey(index: number, key: Value): void; + } + interface MapConstructor { + new (length: number): Map; + (length: number): Map; + } + export const Map: MapConstructor; + + // *** Sass Error *** + + export interface Error { + /** + * This property doesn't exist, but its presence forces the typescript + * compiler to properly type check this type. Without it, it seems to + * allow things that aren't types.Error to match it in case statements and + * assignments. + */ + readonly ___SASS_ERROR___: unique symbol; + // why isn't there a getMessage() method? + } + + interface ErrorConstructor { + /** An error return value for async functions. + * For synchronous functions, this can be returned or a standard error object can be thrown. + */ + new (message: string): Error; + /** An error return value for async functions. + * For synchronous functions, this can be returned or a standard error object can be thrown. + */ + (message: string): Error; + } + export const Error: ErrorConstructor + + /* eslint-enable @typescript-eslint/ban-types */ +} + +// *** Top level Constants *** + +export const NULL: types.Null; +export const TRUE: types.Boolean; +export const FALSE: types.Boolean; +export const info: string; +export declare function render(options: Options, callback: SassRenderCallback): void; +export declare function renderSync(options: SyncOptions): Result; diff --git a/types/node-sass/node-sass-tests.ts b/types/node-sass/node-sass-tests.ts index 4de32d7d06..bc057f866d 100644 --- a/types/node-sass/node-sass-tests.ts +++ b/types/node-sass/node-sass-tests.ts @@ -1,23 +1,49 @@ import * as sass from 'node-sass'; -sass.render({ - file: '/path/to/myFile.scss', - data: 'body{background:blue; a{color:black;}}', - importer: function(url, prev, done) { - someAsyncFunction(url, prev, function(result) { - if (result == null) { - // return null to opt out of handling this path - // compiler will fall to next importer in array (or its own default) - return null; - } - // only one of them is required, see section Sepcial Behaviours. - done({ file: result.path }); - done({ contents: result.data }); - }); - }, - includePaths: ['lib/', 'mod/'], - outputStyle: 'compressed' -}, function(error, result) { // node-style callback from v3.0.0 onwards +console.log(sass.info); + +const syncImporter: sass.SyncImporter = function(url, prev) { + if (url.startsWith('!')) { + return sass.NULL; + } + if (url.endsWith('?')) { + return sass.types.Error("cannot question mark"); + } + console.log(typeof this.callback); // "undefined" + return { file: [prev, url].join('/') }; +}; + +const asyncImporter: sass.AsyncImporter = function(url, prev, done) { + if (url.startsWith('!')) { + // shouldn't really call twice, just checking for compiler validity + done(null); + done(sass.NULL); + } + if (url.endsWith('?')) { + // shouldn't really call twice, just checking for compiler validity + done(new sass.types.Error('Cannot accept this file')); + done(new Error('Cannot accept this file')); + } else { + console.log(this.options.file); // "string" + console.log(typeof this.callback); // "function" + done({ file: [prev, url].join('/') }); + } +}; + +const anotherAsyncImporter: sass.AsyncImporter = function (url, prev, done) { + someAsyncFunction(url, prev, function (result) { + if (result == null) { + // return null to opt out of handling this path + // compiler will fall to next importer in array (or its own default) + done(null); + } + // only one of them is required, see section Special Behaviors. + done({ file: result.path }); + done({ contents: result.data }); + }); +} + +const handleAsyncResult: sass.SassRenderCallback = function(error, result) { // node-style callback from v3.0.0 onwards if (error) { console.log(error.status, error.column, error.message, error.line); } @@ -28,21 +54,143 @@ sass.render({ // or better console.log(JSON.stringify(result.map)); // note, JSON.stringify accepts Buffer too } -}); +}; + +const syncFunction: Record = { + "pow($base, $exp)": function ($base, $exp) { + console.log(this.options.file); // "string" + console.log(typeof this.callback); // "undefined" + if ($base instanceof sass.types.Number && $exp instanceof sass.types.Number) { + if ($base.getUnit() !== "" || $exp.getUnit() !== "") { + throw new Error("Cannot have units in an exponent"); + } + return new sass.types.Number(Math.pow($base.getValue(), $exp.getValue())); + } else { + throw new Error("Number expected"); + } + } +}; + +const syncVarArg: Record = { + "add-all($n1, $n2, $ns...)": function($n1, $n2, $ns) { + if (!($n1 instanceof sass.types.Number)) { + throw new Error("Expected a number"); + } + if (!($n2 instanceof sass.types.Number)) { + throw new Error("Expected a number"); + } + let unit = $n1.getUnit(); + if ($n2.getUnit() !== unit) { + throw new Error("units don't match"); + } + let accum = $n1.getValue() + $n2.getValue(); + $ns.forEach(function ($n) { + if (!($n instanceof sass.types.Number)) { + throw new Error("Expected a number"); + } + if ($n.getUnit() !== unit) { + throw new Error("units don't match"); + } + accum = accum + $n.getValue(); + }); + return sass.types.Number(accum, unit); + } +}; + +const syncFunctions: Record = {...syncFunction, ...syncVarArg}; + +const asyncFunction: Record = { + "pow-async($base, $exp)": function ($base, $exp, done) { + console.log(this.options.file); // "string" + console.log(typeof this.callback); // "function" + if ($base instanceof sass.types.Number && $exp instanceof sass.types.Number) { + if ($base.getUnit() !== "" || $exp.getUnit() !== "") { + done(new sass.types.Error("Cannot have units in an exponent")); + } + done(new sass.types.Number(Math.pow($base.getValue(), $exp.getValue()))); + } else { + done(new sass.types.Error("Number expected")); + } + } +}; + +const asyncVarArg: Record = { + "add-all-async($n1, $n2, $ns...)": function($n1, $n2, $ns, done) { + if (!($n1 instanceof sass.types.Number)) { + done(new sass.types.Error("Expected a number")); + return; + } + if (!($n2 instanceof sass.types.Number)) { + done(new sass.types.Error("Expected a number")); + return; + } + let unit = $n1.getUnit(); + if ($n2.getUnit() !== unit) { + done(new sass.types.Error("units don't match")); + return; + } + let accum = $n1.getValue() + $n2.getValue(); + for (let i = 0; i < $ns.length; i++) { + let $n = $ns[i]; + if (!($n instanceof sass.types.Number)) { + done(new sass.types.Error("Expected a number")); + return; + } + if ($n.getUnit() !== unit) { + done(new sass.types.Error("units don't match")); + return; + } + accum = accum + $n.getValue(); + + } + done(sass.types.Number(accum, unit)); + } +}; + +const asyncFunctions: Record = {...asyncFunction, ...asyncVarArg}; + +const functions: sass.FunctionDeclarations = {...syncFunctions, ...asyncFunctions}; + +sass.render({ + file: '/path/to/myFile.scss', + data: 'body{background:blue; a{color:black;}}', + functions, + importer: [anotherAsyncImporter, asyncImporter, syncImporter], + includePaths: ['lib/', 'mod/'], + outputStyle: 'compressed' +}, handleAsyncResult); + // OR + +sass.render({ + file: '/path/to/myFile.scss', + data: 'body{background:blue; a{color:black;}}', + importer: asyncImporter, + includePaths: ['lib/', 'mod/'], + outputStyle: 'compressed' +}, handleAsyncResult); + +// OR + +sass.render({ + file: '/path/to/myFile.scss', + data: 'body{background:blue; a{color:black;}}', + importer: syncImporter, + includePaths: ['lib/', 'mod/'], + outputStyle: 'compressed' +}, handleAsyncResult); + +// OR + const result = sass.renderSync({ file: '/path/to/file.scss', data: 'body{background:blue; a{color:black;}}', outputStyle: 'compressed', + functions: syncFunctions, outFile: '/to/my/output.css', sourceMap: true, // or an absolute or relative (to outFile) path sourceMapRoot: '.', - importer: function(url, prev) { - if (url.startsWith('!')) { - return new Error('Cannot accept this file'); - } - return { file: [prev, url].join('/') }; - }, + importer: syncImporter, }); console.log(result.css); @@ -50,6 +198,104 @@ console.log(result.map); console.log(result.stats); function someAsyncFunction(url: string, prev: string, callback: (result: { path: string; data: string }) => void): void { } -function someSyncFunction(url: string, prev: string): { path: string; data: string } { - return null; + +function sameType(v1: V, v2: V): boolean { + return v1.constructor === v2.constructor; } + +// function-based Constructors and instance methods for types +let true1 = sass.types.Boolean(true); +true1.getValue(); // true +let true2 = sass.types.Boolean.TRUE; +let true3 = sass.TRUE; +sameType(true2, true3); +true2 === true3 // true +let false1 = sass.types.Boolean(false); +let false2 = sass.types.Boolean.FALSE; +let false3 = sass.FALSE; +false2 === false3 // true +false1.getValue(); // false +let null1 = sass.types.Null(); +let null2 = sass.types.Null.NULL; +let null3 = sass.NULL; +sameType(null2, null3); +null1 === null2; // true +null1 === null3; // true +let ident = sass.types.String("x"); +ident.getValue(); // 'x' +let stringQuoted = sass.types.String("'x'"); +stringQuoted.getValue(); // '\'x\'' +let number = sass.types.Number(5); +number.getUnit(); // "" +number.getValue(); // 5 +let dimension = sass.types.Number(5, "px"); +dimension.getUnit(); // "px" +let redOpaque = sass.types.Color(240, 15, 0); +redOpaque.getR(); // 240 +redOpaque.getG(); // 15 +redOpaque.getB(); // 0 +redOpaque.getA(); // 1 +let redTranslucent = sass.types.Color(240, 15, 0, 0.5); +redTranslucent.getA(); // 0.5 +let redOpaque2 = sass.types.Color(0xF00F00FF); +redOpaque2.getR(); // 240 +redOpaque2.getG(); // 15 +redOpaque2.getB(); // 0 +redOpaque2.getA(); // 1 +let redTranslucent2 = sass.types.Color(0xF00F007F); +redTranslucent.getA(); // 0.5 +let spaceList1 = sass.types.List(1); +spaceList1.getLength(); // 1 +spaceList1.getSeparator(); // false +spaceList1.setValue(0, ident); +spaceList1.setValue(0, true1); +spaceList1.setValue(0, false1); +spaceList1.setValue(0, null1); +spaceList1.setValue(0, dimension); +spaceList1.setValue(0, redOpaque); +spaceList1.getValue(0) === redOpaque; // true +let spaceList2 = sass.types.List(1, false); +spaceList2.setValue(0, sass.types.String("s")); +let commaList1 = sass.types.List(2, true); +commaList1.getLength(); // 2 +commaList1.getSeparator(); // true (it's a comma) +commaList1.setValue(0, spaceList1); +commaList1.setValue(2, spaceList2); +let map1 = sass.types.Map(2); +map1.getLength(); // 2 +map1.setKey(0, ident); +map1.setValue(0, spaceList1); +ident === map1.getKey(0); // true +spaceList1 === map1.getValue(1); // true +sameType(ident, map1.getKey(0)); // true +let error = new sass.types.Error("message"); + +function valuesOf(enumerable: sass.types.Enumerable): sass.types.Value[] { + let values = new Array(); + for (let i = 0; i < enumerable.getLength(); i++) { + values.push(enumerable.getValue(i)); + } + return values; +} + +let arr = valuesOf(map1); +console.dir(arr); +arr = valuesOf(commaList1); +console.dir(arr); + +// new-based Constructors +// boolean and null raise a runtime error if constructed with new. +// let newTrue = new sass.types.Boolean(true); +// let newFalse = new sass.types.Boolean(false); +// let newNull = new sass.types.Null(); +let newIdent = new sass.types.String("x"); +let newNumber = new sass.types.Number(5); +let newDimension = new sass.types.Number(5, "px"); +let newRedOpaque = new sass.types.Color(240, 15, 0); +let newRedTranslucent = new sass.types.Color(240, 15, 0, 0.5); +let newRedOpaque2 = new sass.types.Color(0xF00F00FF); +let newSpaceList1 = new sass.types.List(1); +let newSpaceList2 = new sass.types.List(1, false); +let newCommaList1 = new sass.types.List(2, true); +let newMap1 = new sass.types.Map(2); +let newError = new sass.types.Error("message"); \ No newline at end of file diff --git a/types/node-sass/tsconfig.json b/types/node-sass/tsconfig.json index a1e4cdb079..172d6270c7 100644 --- a/types/node-sass/tsconfig.json +++ b/types/node-sass/tsconfig.json @@ -6,7 +6,7 @@ ], "noImplicitAny": true, "noImplicitThis": true, - "strictNullChecks": false, + "strictNullChecks": true, "strictFunctionTypes": true, "baseUrl": "../", "typeRoots": [