- 
                Notifications
    You must be signed in to change notification settings 
- Fork 834
Description
Instructions for Adding --typecheck-only Support to F# Interactive Scripts
Problem Statement
The --typecheck-only flag already exists for F# project compilation but is not supported for .fsx script files in F# Interactive (FSI). Currently, there's no way to type-check scripts without executing them through the FSI command line. This feature would allow developers to validate script syntax and types without running potentially side-effect-producing code.
Implementation Steps
1. Add Command Line Option
Add the --typecheck-only option to the FSI command line parser. Insert a new CompilerOption in the advanced options section:
CompilerOption("typecheck-only", "", OptionUnit(fun () -> tcConfigB.typeCheckOnly <- true), None, Some("Type-check only, don't execute"))This should be added alongside other advanced options like exec, gui, quiet, etc.
2. Modify ProcessInputs Function
The core implementation goes in the ProcessInputs function. In 2 , add a check after CheckClosedInputSet and before ProcessTypedImpl:
let tcState, topCustomAttrs, declaredImpls, tcEnvAtEndOfLastInput =
    lock tcLockObject (fun _ ->
        CheckClosedInputSet(
            ctok,
            (fun () -> diagnosticsLogger.CheckForRealErrorsIgnoringWarnings),
            tcConfig,
            tcImports,
            tcGlobals,
            Some prefixPath,
            tcState,
            eagerFormat,
            inputs
        ))
// Add this check after CheckClosedInputSet
if tcConfig.typeCheckOnly then
    raise StopProcessing
let codegenResults, optEnv, fragName =
    ProcessTypedImpl(...)3. Exception Handling
The StopProcessing exception is already handled . This infrastructure will properly catch the exception and stop processing without executing the script.
Testing Implementation
Test Location and Structure
All tests should be added to the FSharp.Compiler.ComponentTests project.
Create a new test file:
tests/FSharp.Compiler.ComponentTests/Scripting/TypeCheckOnlyTests.fs
Test Implementation
module FSharp.Compiler.ComponentTests.Scripting.TypeCheckOnlyTests
open Xunit
open FSharp.Test
open FSharp.Test.Compiler
[<Fact>]
let ``typecheck-only flag works for valid script``() =
    Fsx """
let x = 42
printfn "This should not execute"
"""
    |> withOptions ["--typecheck-only"]
    |> compile
    |> shouldSucceed
[<Fact>]
let ``typecheck-only flag catches type errors``() =
    Fsx """
let x: int = "string"  // Type error
"""
    |> withOptions ["--typecheck-only"]
    |> compile
    |> shouldFail
    |> withDiagnostics [
        (Error 1, Line 2, Col 14, Line 2, Col 22, "This expression was expected to have type\n    'int'    \nbut here has type\n    'string'")
    ]
[<Fact>]
let ``typecheck-only flag prevents execution side effects``() =
    Fsx """
System.IO.File.WriteAllText("test-file.txt", "should not be created")
let x = 42
"""
    |> withOptions ["--typecheck-only"]
    |> compile
    |> shouldSucceed
    // Verify file was not created (test would need additional verification logic)Project File Update
Add the new test file:
<Compile Include="Scripting/TypeCheckOnlyTests.fs" />Test Utilities
The ComponentTests project references Test utilities , which provides testing utilities like Fsx, withOptions, compile, shouldSucceed, and shouldFail.
Key Implementation Notes
- 
The --typecheck-onlyflag already exists in the core F# compiler configuration (TcConfigBuilder), so you're primarily adding FSI-specific handling.
- 
The ProcessInputsfunction is the correct location for this check because it occurs after parsing and type-checking but before code generation and execution.
- 
The StopProcessingexception mechanism is already established in FSI for handling compilation-stopping conditions.
- 
All new tests should use the ComponentTests project following modern F# testing practices. 
This implementation will allow users to run fsi --typecheck-only script.fsx to validate script correctness without execution.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status